Метод проти обчислених у Vue


178

У чому головна відмінність методу від обчисленого значення у Vue.js?

Вони виглядають однаково і взаємозамінно.


Може бути корисним для вас: vuejs.org/v2/guide/computed.html#Computed-Properties
DunDev

1
@xDreamCoding Відповідь, яку ви посилаєте, трапляється дійсно для вирішення цього питання, але жодним чином це питання не є дублікатом. Плюс він більш відомий.
Ромен Вінсент

Зверніться до документації, яка висвітлює цю тему під заголовком Обчислювані властивості та методи: vuejs.org/v2/guide/computed.html
Kshitij Dhyani

Відповіді:


243

Обчислені значення та методи сильно відрізняються у Vue і, безумовно, не є взаємозамінними у більшості випадків.

Обчислена власність

Більш підходящою назвою обчисленої величини є обчислена властивість . Насправді, коли Vue інстанціюється, обчислювані властивості перетворюються у властивість Vue з геттером, а іноді і сеттером. В основному ви можете вважати обчислене значення як похідне значення, яке буде автоматично оновлюватися щоразу, коли одне з базових значень, що використовується для його обчислення, буде оновлено. Ви не називаєте обчислювані, і він не приймає жодних параметрів. Ви посилаєтесь на обчислюване властивість так само, як і на властивість даних. Ось класичний приклад з документації :

computed: {
  // a computed getter
  reversedMessage: function () {
    // `this` points to the vm instance
    return this.message.split('').reverse().join('')
  }
}

На що посилається в DOM так:

<p>Computed reversed message: "{{ reversedMessage }}"</p>

Обчислені значення дуже цінні для маніпулювання даними, які існують у вашому Vue. Кожен раз, коли ви хочете фільтрувати або трансформувати свої дані, зазвичай для цього використовуєте обчислене значення.

data:{
    names: ["Bob", "Billy", "Mary", "Jane"]
},
computed:{
    startsWithB(){
        return this.names.filter(n => n.startsWith("B"))
    }
}

<p v-for="name in startsWithB">{{name}}</p>

Обчислювані значення також кешуються, щоб уникнути повторного обчислення значення, яке не потрібно перераховувати, коли воно не змінилося (як, наприклад, воно не може бути в циклі).

Метод

Метод - це лише функція, пов'язана з екземпляром Vue. Він буде оцінюватися лише тоді, коли ви його чітко зателефонуєте. Як і всі функції javascript, він приймає параметри і буде переоцінюватися кожного разу, коли він викликається. Методи корисні в одних і тих же ситуаціях, будь-яка функція корисна.

data:{
    names: ["Bob", "Billy", "Mary", "Jane"]
},
computed:{
    startsWithB(){
        return this.startsWithChar("B")
    },
    startsWithM(){
        return this.startsWithChar("M")
    }
},
methods:{
    startsWithChar(whichChar){
        return this.names.filter(n => n.startsWith(whichCharacter))
    }
}

Документація Vue справді хороша і легкодоступна. Рекомендую.


1
якщо є два входи від користувача, як перетворення температури з c в f і навпаки, де обидва входи можуть визначати значення один для одного. Дивіться albireo.ch/temperatureconverter, і два входи реагують автоматично, не натискаючи кнопку перетворення. який із них найкраще використовувати для обчислень чи методів?
Bootstrap4

2
З тим специфічним інтерфейсом, де з круговою залежністю між входами, я б пішов із методами. codepen.io/Kradek/pen/gROQeB?editors=1010
Берт

2
@ Bootstrap4 Хоча, тут є і один з обчисленими, але його більш складним. codepen.io/Kradek/pen/gROQeB?editors=1010
Берт

3
> Метод ... буде оцінено лише тоді, коли ви його явно викликаєте. Не відповідно до цього відео: youtube.com/watch?v=O14qJr5sKXo
Камерон Хадсон

2
@CameronHudson У прикладі на відео методи оцінюються, оскільки вони прямо посилаються на шаблон . Ось приклад, який демонструє різницю . Зауважте, що методи викликаються лише тоді, коли дані змінюються, якщо вони прямо посилаються на шаблон.
Берт

60

Оскільки @gleenk попросив практичний приклад, щоб зробити очевидними різниці кешу та залежностей між методами та обчислюваними властивостями, я покажу простий сценарій:

app.js

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },
    methods: {
        addToAmethod: function(){
            console.log('addToAmethod');
            return this.a + this.age;
        },
        addToBmethod: function(){
            console.log('addToBmethod');
            return this.b + this.age;
        }
    },
    computed: {
        addToAcomputed: function(){
            console.log('addToAcomputed');
            return this.a + this.age;
        },
        addToBcomputed: function(){
            console.log('addToBcomputed');
            return this.b + this.age;
        }
    }
});

Тут ми маємо 2 методи та 2 обчислені властивості, які виконують одне і те ж завдання. Методи addToAmethod& addToBmethodта обчислені властивості addToAcomputed& addToBcomputedвсі додають +20 (тобто ageзначення) до будь-якого aабо b. Щодо методів, вони обидва викликаються щоразу, коли виконується дія будь-якого із перелічених властивостей, навіть якщо залежності для одного конкретного методу не змінилися. Для обчислених властивостей код виконується лише тоді, коли залежність змінилася; наприклад, одне з певних значень властивості, яке посилається на A або B, запустить addToAcomputedабо addToBcomputed, відповідно,

Метод та обчислювані описи здаються досить схожими, але, як @Addullah Khan вже вказав це, вони не те саме ! Тепер спробуємо додати трохи html для виконання всього разом і подивимось, де різниця.

Демонстраційний випадок методу

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },
    methods: {
        addToAmethod: function(){
            console.log('addToAmethod');
            return this.a + this.age;
        },
        addToBmethod: function(){
            console.log('addToBmethod');
            return this.b + this.age;
        }
    }
});
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>VueJS Methods - stackoverflow</title>
            <link href="style.css" rel="stylesheet" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
    
        </head>
        <body>
            <div id="vue-app">
                <h1>Methods</h1>
                <button v-on:click="a++">Add to A</button>
                <button v-on:click="b++">Add to B</button>
                <p>Age + A = {{ addToAmethod() }}</p>
                <p>Age + B = {{ addToBmethod() }}</p>
            </div>
        </body>
        
        <script src="app.js"></script>
    </html>

Пояснений результат

Коли я натискаю кнопку "Додати в A" , всі методи викликаються (див. Результат екрана журналу консолі вище), addToBmethod()також виконується, але я не натискав кнопку "Додати в B" ; значення властивості, яке посилається на B, не змінилося. Така ж поведінка виникає, якщо ми вирішимо натиснути кнопку "Додати в B" , тому що знову обидва методи будуть викликатися незалежно від змін залежності. Відповідно до цього сценарію, це погана практика, оскільки ми виконуємо методи щоразу, навіть коли залежності не змінюються. Це дійсно витрачає ресурси, оскільки немає кешу значень властивостей, які не змінилися.

метод кнопковий метод

Демонстраційний випадок обчисленої власності

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },

    computed: {
        addToAcomputed: function(){
            console.log('addToAcomputed');
            return this.a + this.age;
        },
        addToBcomputed: function(){
            console.log('addToBcomputed');
            return this.b + this.age;
        }
    }
});
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>VueJS Computed properties - stackoverflow</title>
            <link href="style.css" rel="stylesheet" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
        </head>
        <body>
            <div id="vue-app">
                <h1>Computed Properties</h1>
                <button v-on:click="a++">Add to A</button>
                <button v-on:click="b++">Add to B</button>
                <p>Age + A = {{ addToAcomputed }}</p>
                <p>Age + B = {{ addToBcomputed }}</p>
            </div>
        </body>
        
        <script src="app.js"></script>
    </html>

Пояснений результат

Коли я натискаю кнопку "Додати в A" , addToAcomputedвикликається тільки обчислена властивість , оскільки, як ми вже говорили, обчислювані властивості виконуються лише тоді, коли залежність змінилася. Оскільки я не натискав кнопку "Додати в B", а значення властивості віку для B не змінилося, немає підстав викликати та виконувати обчислене властивість addToBcomputed. Отже, у певному сенсі обчислювана властивість підтримує "те ж незмінне" значення для властивості B, як певний кеш. І в цій обставині це вважається хорошою практикою .

обчислюється кнопка обчислена


3
Чому всі методи виконуються при натисканні 1 кнопки? У чому причина / логіка?
Bsienn

1
@Bsienn - це гарне запитання: причина полягає в тому, що в основному Vue не знає, який із методів потрібно запустити, залежно від того, що оновлено. І це такий вид операцій, які роблять обчислювані властивості, вони спостерігають за змінними, які потрібно обчислити або перерахувати, і вони виконуються лише за потреби.
Джуліо Бамбіні

2
І які причини використання методів? Схоже, що обчислювані властивості просто кращі (якщо припустити, що ми говоримо про методи "отримати") ...
user3529607

5
@ user3529607, але обчислювані властивості не отримують аргументів.
Родіон Головушкін

3
@ user3529607 З того, що я можу зрозуміти, методи можуть бути корисні під час монтажу або створення екземпляра vue. Те ж неможливо зробити з обчислюваними властивостями. Крім того, ми повинні повернути значення для обчислених властивостей.
Дхаваль Чхеда

13

Від docs

..comобчислені властивості кешуються залежно від їх залежностей. Обчислена властивість буде переоцінюватися лише тоді, коли змінилися деякі її залежності.

Якщо ви хочете кешувати дані, використовуйте властивості Computed з іншого боку, якщо ви не хочете, щоб дані кешувались, використовуйте прості властивості методу.


1
Привіт, ви можете написати корисний приклад, щоб показати різницю у практичному використанні?
Девід Де Маестрі

@gleenk Я додам практичний приклад, щоб показати вам цю різницю кешу / залежності між методами та обчисленими властивостями. Сподіваюся, ви це оціните.
Джуліо Бамбіні

Дякую @GiulioBambini
Davide De Maestri

7

Одна з різниць між обчисленими та методами. Припустимо, у нас є функція, яка повертає лічильне значення. (Лічильник просто змінна). Давайте подивимось, як поводиться функція як в обчисленій, так і в методі

Обчислено

У перший час виконання код всередині функції буде виконаний, і vuejs збереже значення лічильника в кеші (для швидшого доступу). Але коли ми знову викликаємо функцію, vuejs не буде знову виконувати код, написаний всередині цієї функції. Він спочатку перевіряє будь-які зміни, внесені в лічильник чи ні. Якщо будь-які зміни будуть внесені, то тільки він повторно виконає код, який знаходиться всередині цієї функції. Якщо не буде внесено змін у лічильник, vuejs знову не виконає функцію. Він просто поверне попередній результат з кешу.

Метод

Це подібно до звичайного методу в javascript. Щоразу, коли ми викликаємо метод, він завжди виконуватиме код всередині функції, незалежно від змін, внесених до лічильника.

Метод завжди буде виконувати код незалежно від змін у коді. де, як обчислено, буде повторно виконувати код тоді, лише якщо змінено одне із значень його залежності. Інакше це дасть нам попередній результат із кеша без повторного виконання


6

Ось розбивка цього питання.

Коли використовувати методи

  • Реагувати на якусь подію, що відбувається в DOM
  • Виклик функції, коли щось відбувається у вашому компоненті.
  • Ви можете викликати метод із обчислених властивостей або спостерігачів.

Коли використовувати обчислені властивості

  • Вам потрібно скласти нові дані з існуючих джерел даних
  • У вас є змінна, яку ви використовуєте у своєму шаблоні, побудованому з одного або декількох властивостей даних
  • Ви хочете зменшити складне, вкладене ім’я властивості до більш зрозумілого та зручного у користуванні (але оновити його, коли початкова властивість зміниться)
  • Вам потрібно посилатись на значення з шаблону. У цьому випадку найкраще створити обчислену властивість, оскільки вона кешована.
  • Вам потрібно прослухати зміни більш ніж одного властивості даних

2

Обчислені властивості

Обчислювані властивості називаються також обчисленими значеннями. Це означає, що вони оновлюються і можуть бути змінені в будь-який час. Крім того, він кешує дані, поки вони не змінюються. Коли Vue інстанціюється, обчислювані властивості перетворюються у властивість.

Ще одне, що я хочу поділитися: Ви не можете передавати жоден параметр у обчислених властивостях, тому під час виклику будь-якого комп’ютерного властивості не потрібні дужки.

Методи

Методи такі ж, як функція і працюють однаково. Крім того, метод нічого не робить, якщо ви його не викликаєте. Також, як і всі функції javascript, він приймає параметри і буде переоцінюватися кожного разу, коли він викликається. Після цього вони не можуть кешувати значення

У методі виклику круглих дужок є, і ви можете надіслати один або кілька параметрів в цьому.


0

Натрапили на те саме питання. Мені це зрозуміліше так:

  1. Коли Vue.js бачить v-on directiveнаступний за ним метод, він точно знає, який метод викликати і коли його викликати.
<button v-on:click="clearMessage">Clear message</button> // @click
// method clearMessage is only called on a click on this button

<input v-model="message" @keyup.esc="clearMessage" @keyup.enter="alertMessage" />
/* The method clearMessage is only called on pressing the escape key
and the alertMessage method on pressing the enter key */
  1. Коли метод викликається без нього,v-on directive він буде викликатися щоразу, коли подія запускається на сторінці, яка оновлює DOM (або просто потребує повторного відтворення частини сторінки). Навіть коли цей метод не має нічого спільного з ініціюванням події.
<p>Uppercase message: {{ messageUppercase() }}</p>
methods: {
   messageUppercase() {
      console.log("messageUpercase");
      return this.message.toUpperCase();
   }
}
/* The method `messageUppercase()` is called on every button click, mouse hover 
or other event that is defined on the page with the `v-on directive`. So every
time the page re-renders.*/
  1. Обчислена властивість викликається лише при зміні значення властивості, на яке посилається thisслово в його визначенні функції.
<p>Uppercase message: {{ messageUppercase }}</p> 
data() {
 return {
    message: "I love Vue.js"
   }
 },
computed: {
 messageUppercase() {
    console.log("messageUpercase");
    return this.message.toUpperCase();
 }
}
/* The computed property messageUppercase is only called when the propery message is
changed. Not on other events (clicks, mouse hovers,..) unless of course a specific 
event changes the value of message.  */

Перевагою тут є те, що найкраще застосовувати computedвластивості, якщо метод не викликається разом із v-on directive.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.