В чем основная разница между methods и computed значением в Vue.js?

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

Ответы (10)

Вычисляемые значения и методы сильно отличаются в Vue и определенно не взаимозаменяемы в большинстве случаев.

Компонуемое свойство

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

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

На него ссылаются в DOM следующим образом:

Computed reversed message: "{{ reversedMessage }}"

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

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

{{name}}

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

Метод

Метод - это просто функция, привязанная к экземпляру 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(whichChar))
    }
}

Документация по Vue документация действительно хороша и легко доступна. Я рекомендую ее.

Поскольку @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',
    данные: {
        a: 0,
        b: 0,
        возраст: 20
    },
    методы: {
        addToAmethod: function(){
            console.log('addToAmethod');
            return this.a + this.age;
        },
        addToBmethod: function(){
            console.log('addToBmethod');
            return this.b + this.age;
        }
    }
});

    
        
            
            Методы VueJS - stackoverflow
            
            
    
        
        
            

Методы

Возраст + A = {{ addToAmethod() }}

Возраст + B = {{ addToBmethod() }}

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

Когда я нажимаю на кнопку "Добавить к A", вызываются все методы (см. результат консольного лога выше), также выполняется addToBmethod(), но я не нажимал кнопку "Добавить к B"; значение свойства, ссылающегося на B, не изменилось. Такое же поведение будет, если мы решим нажать кнопку "Добавить к B", потому что снова оба метода будут вызваны независимо от изменения зависимости. Согласно данному сценарию, это плохая практика, потому что мы выполняем методы каждый раз, даже когда зависимости не изменились. Это очень ресурсозатратно, поскольку не существует кэша для значений свойств, которые не изменились.

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

Демонстрация случая свойства Computed

new Vue({
    el: '#vue-app',
    данные: {
        a: 0,
        b: 0,
        возраст: 20
    },

    вычисляется: {
        addToAcomputed: function(){
            console.log('addToAcomputed');
            return this.a + this.age;
        },
        addToBcomputed: function(){
            console.log('addToBcomputed');
            return this.b + this.age;
        }
    }
});

    
        
            
            VueJS Вычисляемые свойства - stackoverflow
            
            
        
        
            

Вычисленные свойства

Возраст + A = {{ addToAcomputed }}

Возраст + B = {{ addToBcomputed }}

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

Когда я нажимаю на кнопку "Добавить к A", вызывается только вычисляемое свойство addToAcomputed, потому что, как мы уже говорили, вычисляемые свойства выполняются только тогда, когда зависимость изменилась. А поскольку я не нажимал кнопку "Добавить к B" и значение свойства age для B не изменилось, то нет причин вызывать и выполнять вычисляемое свойство addToBcomputed. Таким образом, в определенном смысле вычисляемое свойство сохраняет "неизменное" значение для свойства B как своего рода кэш. И в данном случае это считается хорошей практикой.

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

Вычисленные свойства

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

Еще одна вещь, которой я хочу поделиться: в вычисляемых свойствах нельзя передавать какие-либо параметры, поэтому при вызове любого вычислительного свойства не требуется скобка.

Методы

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

В вызове метода есть скобка, в которой можно передать один или несколько параметров.

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

.

Вычислено

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

Метод

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

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

.

Наткнулся на тот же вопрос. Для меня это более понятно так:

  1. Когда Vue.js видит директиву v-on, за которой следует метод, он точно знает какой метод вызвать и когда его вызвать.
 // @click
// метод clearMessage вызывается только при нажатии на эту кнопку


/* Метод clearMessage вызывается только при нажатии клавиши escape
а метод alertMessage - при нажатии клавиши Enter */.
  1. Когда метод вызывается без директивы v-on, он будет вызываться каждый раз, когда на странице срабатывает событие, которое обновляет DOM (или просто требует повторного отображения части страницы). Даже если этот метод не имеет никакого отношения к вызываемому событию.

Сообщение в верхнем регистре: {{ messageUppercase() }}

методы: { messageUppercase() { console.log("messageUpercase"); return this.message.toUpperCase(); } } /* Метод `messageUppercase()` вызывается при каждом нажатии кнопки, наведении мыши или другом событии, определенном на странице с помощью директивы `v-on`. Таким образом, каждый при повторном рендеринге страницы*/.
  1. Вычисляемое свойство вызывается только при изменении значения свойства, на которое ссылается это слово в определении функции.

Сообщение в верхнем регистре: {{ messageUppercase }}

data() { return { сообщение: "Я люблю Vue.js" } }, computed: { messageUppercase() { console.log("messageUpercase"); return this.message.toUpperCase(); } } /* Вычисляемое свойство messageUppercase вызывается только в том случае, если собственное сообщение изменяется. Не при других событиях (щелчки, наведение мыши, ...), если, конечно, конкретное событие изменяет значение message. */

Вывод здесь заключается в том, что лучше всего использовать свойства computed в случае, если метод не вызывается с помощью директивы v-on.

Из docs

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

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

Простой способ в соответствии с документацией vueJs:

Для сравнения, при вызове метода функция будет выполняться всегда, когда происходит повторный рендеринг.

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

Здесь мы рассмотрим этот вопрос.

Когда использовать методы

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

Когда использовать вычисляемые свойства

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

Я постараюсь дополнить ответы других пользователей. Этот пример и объяснения помогли мне полностью понять суть вычисляемых свойств. Надеюсь, что после прочтения моего сообщения вы тоже поймете это.


Если вам нужно изменить данные, вы должны использовать методы. А когда вам нужно изменить представление существующих данных, вы будете использовать вычисляемые свойства. По мере того как вы будете практиковаться в обеих концепциях, вы будете использовать их с легкостью. Вот несколько основных ключей:

  1. вычисляемые свойства всегда должны возвращать значение;
  2. вычисляемые свойства используются только для преобразования данных, а не для их изменения для нашего презентационного слоя | они не должны изменять существующие данные.

Как вы уже прочитали или после выполнения кода моего примера, вы увидите, что только значения, представленные в вычисляемых свойствах, изменяются (либо внутри метода, либо при вводе пользователем, либо другим способом), вычисляемое свойство пересчитывается и кэшируется. Но каждый раз, когда вызывается метод, он будет выполняться независимо от результата (например, в моем примере, когда значение достигает значения 0, вычисляемое свойство больше не пересчитывается)

.

В примере представлена простая система, где у вас есть:

  • собственные наличные;
  • ваши наличные на банковском счете;
  • возможность снять деньги со своего банковского счета;
  • возможность одолжить некоторую сумму денег у некоторого лица (с помощью денег Инфинити).

new Vue({
  el: '#app',
  данные: {
    бесконечность: Бесконечность,
    значение: 3,
    долг: -6,
    наличные: 9,
    moneyInBank: 15,
  },

  вычислено: {
    computedPropRemainingCashFundsIfPaid: function() {
      console.log('computedPropRemainingCashFundsIfPaid');
      return this.debt + this.cash;
    },
    computedPropRemainingTotalFunds: function() {
      console.log('computedPropRemainingTotalFunds');
      return this.cash + this.moneyInBank + this.debt;
    }
  },
  методы: {
    depositFunds: function(from, to, value, limit = false) {
      if (limit && (this[to] + value) >= 0) { // если вы пытаетесь вернуть большее значение, чем вы должны
        this[from] += this[to];
        this[to] = 0;
      } else if (this[from] > value && this[from] - value >= 0) { // обычный депозит
        this[to] += value;
        this[from] -= value;
      } else { // попытка пополнить счет больше, чем у вас есть
        this[to] += this[from];
        this[from] = 0;
      }
    },
    repayADebt: function() {
      this.value = Math.abs(this.value);
      if (this.debt < 0) {
        this.depositFunds('cash', 'debt', this.value, true);
      }
      console.log('Attempt to repayADebt', this.value);
    },
    lendAmount: function() {
      this.depositFunds('infinity', 'debt', -Math.abs(this.value));
      console.log('Attempt to lendAmount', this.value);
    },
    withdraw: function() {
      if (this.moneyInBank) {
        this.depositFunds('moneyInBank', 'cash', this.value);
      }
      console.log('Попытка вывода', this.value);
    }
  }
});
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  overflow-wrap: break-word;
}

html {
  font-family: "Segoe UI", Tahoma, Geneva, Verdana;
  font-size: 62.5%;
}

body {
  margin: 0;
  font-size: 1.6rem;
}

#app {
  margin: 3rem auto;
  max-width: 50vw;
  padding: 1rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0, 0.26);
}

label,
input {
  margin-bottom: 0.5rem;
  display: block;
  width: 100%;
}

label {
  font-weight: bold;
}

ul {
  list-style: none;
  margin: 1rem 0;
  padding: 0;
}

li {
  margin: 1rem 0;
  padding: 1rem;
  border: 1px solid #ccc;
}

.grid {
  отображение: сетка;
  сетка: 1fr / 1fr min-content 1fr min-content;
  промежуток: 1rem;
  align-items: center;
  margin-bottom: 1rem;
}

.grid> :is(button, input) {
  высота: 3rem;
  margin: 0;
}

.computed-property-desc {
  padding: 1rem;
  background-color: rgba(0, 0, 0, 0, 0.3);
  text-align: justify;
}




  
  
  Первое приложение
  



  

Руководство по вычисленным свойствам

Предположим, что у вас есть {{деньги }}$; И вам нужно заплатить долг={{долг }}

Ваш банковский счет: {{ moneyInBank }}$

Ваши наличные: {{ наличные }}$

Ваш долг: {{ долг }}$

в размере $

computedPropRemainingCashFundsIfPaid/
Доступные средства в случае погашения долга = {{ computedPropRemainingCashFundsIfPaid }}$

computedPropRemainingTotalFunds = {{ computedPropRemainingTotalFunds }}$

Когда вам нужно изменить данные, вы используете методы. А когда вам нужно изменить представление существующих данных, вы будете использовать вычисляемые свойства. По мере того, как вы будете практиковаться в обеих концепциях, вам будет все легче понять, какую из них следует использовать. Очень важные замечания: 1. метод всегда должен возвращать значение; 2. вычисляемые свойства используются только для преобразования данных, а не для их изменения для нашего презентационного слоя | они не должны изменять существующие данные

В vue composition API, который поставляется с Vue 3 и который доступен как плагин для vue 2, методы и вычисляемые свойства имеют другой синтаксис :

.

Примеры :

вычислено :

Это функция, которая по умолчанию принимает в качестве параметра обратный вызов getter и возвращает неизменяемый ref на основе другого свойства, такого как ref, reactive или состояние магазина.

import {computed,ref} from 'vue'

export default{

setup(){
  const count=ref(0);
  
  const doubleCount=computed(()=>count.value*2) 

 return {count,doubleCount} //expose the properties to the template 
 }
}

Методы

Это обычные функции javascript, которые ведут себя одинаково как в Vue, так и в vanilla js, они открыты для шаблона и используются как обработчики событий, их не следует использовать для рендеринга, что может привести к некоторым проблемам, таким как бесконечный рендеринг.

import {computed,ref} from 'vue'

export default{

setup(){
  const count=ref(0);
  
  const doubleCount=computed(()=>count.value*2) 
 
  function increment(){
   ref.value++
 }

 return {count,doubleCount,increment} //expose the properties/functions to the template 
 }
}

Разница :

вычислено :

  • Оценивается как неизменяемое свойство, а не как функция
  • .
  • Она наблюдает другое свойство и возвращает свойство, основанное на этом свойстве.
  • Не может принимать параметр.
  • За ним можно наблюдать, используя свойство watch
  • .

метод :

  • Используется для рефакторинга кода внутри свойства computed/watcher или другой функции
  • Используется в качестве обработчика событий
  • Не следует вызывать внутри шаблона во избежание проблем с отрисовкой.

2022 WebDevInsider