Vue.js中方法和计算值的主要区别是什么?

在我看来,它们是一样的,是可以互换的。


当前回答

我会尽量补充其他成员的回答。这个例子和解释让我完全掌握了计算属性的要点。我希望在看完我的文章后,你也能意识到这一点。


如果需要更改数据,则必须使用方法。当您需要更改现有数据的表示时,您将使用计算属性。当您练习这两个概念时,您将轻松地使用它们。以下是一些奇特的钥匙:

计算属性必须总是返回一个值; 计算属性仅用于转换数据,而不是用于改变我们的表示层|,它们不应该改变或改变现有的数据。

由于您已经阅读了它或在运行我的示例代码之后,您将看到只有在计算属性中显示的值被更改(在方法中或通过用户输入或其他方式),计算属性将被重新计算并缓存。 但是每次调用一个方法时,不管结果如何,它都会被执行(例如,在我的例子中,当一个值达到0时,计算的属性不再被重新计算)

在这个例子中,有一个简单的系统;你有:

自己的现金; 你银行账户里的现金; 可从您的银行帐户提款; 有可能从某人那里借一些钱(无限的钱)。

new Vue({ el: '#app', data: { infinity: Infinity, value: 3, debt: -6, cash: 9, moneyInBank: 15, }, computed: { computedPropRemainingCashFundsIfPaid: function() { console.log('computedPropRemainingCashFundsIfPaid'); return this.debt + this.cash; }, computedPropRemainingTotalFunds: function() { console.log('computedPropRemainingTotalFunds'); return this.cash + this.moneyInBank + this.debt; } }, methods: { depositFunds: function(from, to, value, limit = false) { if (limit && (this[to] + value) >= 0) { // if you try to return greater value than you owe this[from] += this[to]; this[to] = 0; } else if (this[from] > value && this[from] - value >= 0) { // usual deposit this[to] += value; this[from] -= value; } else { // attempt to depost more than you have 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('Attempt to withdraw', 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.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 { display: grid; grid: 1fr / 1fr min-content 1fr min-content; gap: 1rem; align-items: center; margin-bottom: 1rem; } .grid> :is(button, input) { height: 3rem; margin: 0; } .computed-property-desc { padding: 1rem; background-color: rgba(0, 0, 0, 0.3); text-align: justify; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>A First App</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <div id="app"> <h1>Computed Properties Guide</h1> <p style="background-color: bisque;"> Let's assume that you have <span v-once>{{ cash }}</span>$; And you need to pay a debt=<span v-once>{{ debt }}</span> </p> <p>Your bank account: {{ moneyInBank }}$ <button v-on:click="withdraw(value)">Withdrow {{ value }}$ from bank</button></p> <p>Your cash: {{ cash }}$</p> <p>Your debt: {{ debt }}$ <button v-on:click="lendAmount(value)">Lend {{ value }}$ from Infinity</button></p> <div class="grid"> <button v-on:click="repayADebt(value)">Repay a debt</button> <span>in amout of</span> <input type="text" v-model.number="value"> <span>$</span> </div> <p>computedPropRemainingCashFundsIfPaid/<br><mark>Available funds in case of debt repayment</mark> = {{ computedPropRemainingCashFundsIfPaid }}$</p> <p>computedPropRemainingTotalFunds = {{ computedPropRemainingTotalFunds }}$</p> <p class="computed-property-desc">when you need to change data, you will use methods. And When you need to change the presentation of existing data, you will use computed properties. As you practice both concepts, it will become easier which one should you use. Very important notes: 1. it must always return a value; 2. computed properties are only used for transforming data and not for chaning it for our presentation layer | they should not alter or change the existing data</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> </body> </html>

其他回答

根据vueJs文档,一个简单的方法是:

相比之下,每当重新呈现发生时,方法调用将始终运行该函数。

而计算属性只有在其响应性依赖项发生更改时才会重新计算

计算与方法的区别之一。假设我们有一个返回计数器值的函数。(counter只是变量)。让我们看看函数在计算和方法中的行为

计算

At first time of execution the code inside the function will be executed and vuejs will store the counter value in cache(for accessing faster). But when we are again calling the function vuejs will not again execute the code written inside of that function. It first checks any changes made to the counter or not. If any changes made then only it will re-execute the code which is inside that function. If there are no changes made to the counter vuejs will not again execute the function. It will simply return the previous result from the cache.

方法

这就像javascript中的一个普通方法。无论何时调用该方法,它都将始终执行函数内部的代码,而不管对计数器做了什么更改。

方法将始终重新执行代码,而不考虑代码中的更改。其中as computed将重新执行代码,然后只有当它的一个依赖项的值改变了。否则,它将在不重新执行的情况下,向我们提供之前缓存的结果

来自文档

..计算属性是基于它们的依赖项缓存的。计算属性只有在其某些依赖项发生更改时才会重新计算。

如果您希望缓存数据,请使用Computed属性,另一方面,如果您不想缓存数据,请使用简单的Method属性。

computed和methods之间的区别在于,当你在computed中定义一个函数时,它只在答案改变时才从头执行该函数,而methods在每次调用时都从头执行该函数。

我会尽量补充其他成员的回答。这个例子和解释让我完全掌握了计算属性的要点。我希望在看完我的文章后,你也能意识到这一点。


如果需要更改数据,则必须使用方法。当您需要更改现有数据的表示时,您将使用计算属性。当您练习这两个概念时,您将轻松地使用它们。以下是一些奇特的钥匙:

计算属性必须总是返回一个值; 计算属性仅用于转换数据,而不是用于改变我们的表示层|,它们不应该改变或改变现有的数据。

由于您已经阅读了它或在运行我的示例代码之后,您将看到只有在计算属性中显示的值被更改(在方法中或通过用户输入或其他方式),计算属性将被重新计算并缓存。 但是每次调用一个方法时,不管结果如何,它都会被执行(例如,在我的例子中,当一个值达到0时,计算的属性不再被重新计算)

在这个例子中,有一个简单的系统;你有:

自己的现金; 你银行账户里的现金; 可从您的银行帐户提款; 有可能从某人那里借一些钱(无限的钱)。

new Vue({ el: '#app', data: { infinity: Infinity, value: 3, debt: -6, cash: 9, moneyInBank: 15, }, computed: { computedPropRemainingCashFundsIfPaid: function() { console.log('computedPropRemainingCashFundsIfPaid'); return this.debt + this.cash; }, computedPropRemainingTotalFunds: function() { console.log('computedPropRemainingTotalFunds'); return this.cash + this.moneyInBank + this.debt; } }, methods: { depositFunds: function(from, to, value, limit = false) { if (limit && (this[to] + value) >= 0) { // if you try to return greater value than you owe this[from] += this[to]; this[to] = 0; } else if (this[from] > value && this[from] - value >= 0) { // usual deposit this[to] += value; this[from] -= value; } else { // attempt to depost more than you have 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('Attempt to withdraw', 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.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 { display: grid; grid: 1fr / 1fr min-content 1fr min-content; gap: 1rem; align-items: center; margin-bottom: 1rem; } .grid> :is(button, input) { height: 3rem; margin: 0; } .computed-property-desc { padding: 1rem; background-color: rgba(0, 0, 0, 0.3); text-align: justify; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>A First App</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <div id="app"> <h1>Computed Properties Guide</h1> <p style="background-color: bisque;"> Let's assume that you have <span v-once>{{ cash }}</span>$; And you need to pay a debt=<span v-once>{{ debt }}</span> </p> <p>Your bank account: {{ moneyInBank }}$ <button v-on:click="withdraw(value)">Withdrow {{ value }}$ from bank</button></p> <p>Your cash: {{ cash }}$</p> <p>Your debt: {{ debt }}$ <button v-on:click="lendAmount(value)">Lend {{ value }}$ from Infinity</button></p> <div class="grid"> <button v-on:click="repayADebt(value)">Repay a debt</button> <span>in amout of</span> <input type="text" v-model.number="value"> <span>$</span> </div> <p>computedPropRemainingCashFundsIfPaid/<br><mark>Available funds in case of debt repayment</mark> = {{ computedPropRemainingCashFundsIfPaid }}$</p> <p>computedPropRemainingTotalFunds = {{ computedPropRemainingTotalFunds }}$</p> <p class="computed-property-desc">when you need to change data, you will use methods. And When you need to change the presentation of existing data, you will use computed properties. As you practice both concepts, it will become easier which one should you use. Very important notes: 1. it must always return a value; 2. computed properties are only used for transforming data and not for chaning it for our presentation layer | they should not alter or change the existing data</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> </body> </html>