Метод против вычисленного в Vue

178

В чем основное различие между методом и вычисленным значением в Vue.js?

Они выглядят одинаково и взаимозаменяемы.

Bootstrap4
источник
Может быть полезно для вас: vuejs.org/v2/guide/computed.html#Computed-Properties
DunDev
1
@xDreamCoding Ответ, на который вы ссылаетесь, действительно отвечает на этот вопрос, но ни в коем случае этот вопрос не является дубликатом. Плюс это более известный.
Ромен Винсент
Обратитесь к документации, которая проливает некоторый свет на эту тему под заголовком «Вычисляемые свойства в сравнении с методами»: vuejs.org/v2/guide/computed.html
Кшитий Дхиани,

Ответы:

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/temperaconverter, и два входа реагируют автоматически, не нажимая кнопку преобразования. какой из них лучше всего подходит для вычисления или методов?
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, соответственно.

Метод и вычисленные описания кажутся довольно схожими, но, как @Abdullah 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» , потому что снова оба метода будут вызваны независимо от изменений зависимостей. В соответствии с этим сценарием это плохая практика, потому что мы выполняем методы каждый раз, даже когда зависимости не изменились. Это действительно потребляет много ресурсов, потому что нет кэша для значений свойств, которые не изменились.

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

Демо-версия Computed property case

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», а значение свойства age для B не изменилось, нет причин вызывать и выполнять вычисляемое свойство addToBcomputed. Таким образом, в определенном смысле вычисляемое свойство поддерживает «такое же неизменное» значение для свойства B, как своего рода кеш. И в этом случае это считается хорошей практикой .

вычисленное кнопка вычисляется

Джулио Бамбини
источник
3
Почему все методы выполняются при нажатии 1 кнопки? В чем причина / логика?
Бсиенн
1
@Bsienn, это хороший вопрос: причина в том, что в основном Vue не знает, какой из методов нужно запустить, в зависимости от того, что обновилось. И это тот тип операций, которые выполняют вычисляемые свойства, они следят за переменными, которые должны быть вычислены или пересчитаны, и выполняются только при необходимости.
Джулио Бамбини
2
И каковы причины использования методов? Похоже, что вычисленные свойства лучше (если мы говорим о методах get) ...
user3529607
5
@ user3529607 но вычисленные свойства не получают аргументов.
Родион Головушкин
3
@ user3529607 Насколько я понимаю, методы могут быть полезны при монтировании или создании экземпляра vue. То же самое нельзя сделать с вычисленными свойствами. Также мы должны вернуть значение для вычисленных свойств.
Давал Чхеда
13

Из docs

..computed свойства кэшируются на основе их зависимостей. Вычисленное свойство будет переоцениваться только тогда, когда некоторые его зависимости были изменены.

Если вы хотите, чтобы данные кэшировались, используйте Computed свойства с другой стороны, если вы не хотите, чтобы данные кэшировались, используйте простые свойства Method.

Абдулла Хан
источник
1
Привет, не могли бы вы написать полезный пример, чтобы показать разницу в практическом использовании?
Давид де Маэстри
@gleenk Я добавлю практический пример, чтобы показать вам разницу между кэшем и зависимостями между методами и вычисляемыми свойствами. Я надеюсь, вы оцените это.
Джулио Бамбини
Спасибо @GiulioBambini
Davide De Maestri
7

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

Компьютерный

В первый раз выполнения код внутри функции будет выполнен, и vuejs сохранит значение счетчика в кеше (для более быстрого доступа). Но когда мы снова вызываем функцию, vuejs больше не будет выполнять код, написанный внутри этой функции. Сначала проверяются любые изменения, внесенные в счетчик или нет. Если будут внесены какие-либо изменения, то только он повторно выполнит код, который находится внутри этой функции. Если в счетчике нет изменений, vuejs больше не будет выполнять функцию. Он просто вернет предыдущий результат из кеша.

метод

Это так же, как обычный метод в JavaScript. Каждый раз, когда мы вызываем метод, он всегда выполняет код внутри функции независимо от изменений, внесенных в счетчик.

Метод всегда повторно выполняет код независимо от изменений в коде. где as computed будет выполнять код повторно только в том случае, если изменилось одно из значений его зависимости. В противном случае он выдаст нам предыдущий результат из кэша без повторного выполнения.

ПАЛЛАМОЛЛА САИ
источник
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. Свойство Computed вызывается только при изменении значения свойства, на которое ссылается 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.

DarkLite1
источник