Vue 中的方法与计算

IT技术 javascript methods vue.js vuejs2 computed-properties
2021-01-29 13:47:13

Vue.js 中amethods和 acomputed之间的主要区别是什么

它们看起来相同并且可以互换。

6个回答

Vue 中的计算值和方法非常不同,并且在大多数情况下绝对不能互换。

计算属性

计算值的更合适的名称是计算属性事实上,当 Vue 被实例化时,计算属性被转换成 Vue 的属性,带有一个 getter,有时还有一个 setter。基本上,您可以将计算值视为派生值,只要用于计算它的基础值之一更新,该值就会自动更新。你不调用一个计算,它不接受任何参数。您可以像引用数据属性一样引用计算属性。这是文档中的经典示例

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 上存在的数据非常有value。每当您想要过滤或转换数据时,通常都会为此目的使用计算值。

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(whichChar))
    }
}

Vue 的文档非常好且易于访问。我推荐它。

如果用户有两个输入,例如从 c 到 f 的温度转换,反之亦然,其中两个输入都可以确定彼此的值。请参阅albireo.ch/temperatureconverter,两个输入无需按下转换按钮即可自动反应。哪一个最适合使用计算或方法?
2021-03-15 13:47:13
@CameronHudson 在视频的示例中,评估方法是因为它们在模板中被显式引用下面是一个演示差异的示例注意,当数据变化的方法只被调用,如果它们在模板中明确提到。
2021-03-22 13:47:13
> 一个方法……只有在你明确调用它时才会被评估。不是根据这个视频:youtube.com/watch?v=O14qJr5sKXo
2021-03-28 13:47:13
@Bootstrap4 虽然,这里也有一个计算器,但它更复杂。codepen.io/Kradek/pen/gROQeB?editors=1010
2021-04-05 13:47:13
有了那个特定的UI,其中输入之间的循环关系,我会去使用方法。codepen.io/Kradek/pen/gROQeB?editors=1010
2021-04-09 13:47:13

由于@gleenk 要求提供一个实际示例来说明方法和计算属性之间的缓存和依赖项差异,因此我将展示一个简单的场景:

应用程序.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值)添加到ab关于方法,每次任何列出的属性执行操作时都会调用它们,即使某个特定方法的依赖项没有更改。对于计算属性,只有在依赖项发生变化时才会执行代码;例如,引用 A 或 B 的特定属性值之一将分别触发addToAcomputedaddToBcomputed

方法和计算描述看起来非常相似,但正如@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”按钮,则会出现相同的行为,因为这两个方法将再次独立于依赖项更改而被调用。根据这种情况,这是不好的做法,因为我们每次都在执行这些方法,即使依赖项没有改变。这确实很消耗资源,因为没有对未更改的属性值进行缓存。

方法 按钮法

计算属性案例演示

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的 age 属性值没有改变,所以没有理由调用和执行计算属性addToBcomputed因此,从某种意义上说,计算属性就像一种缓存一样为 B 属性维护“相同的不变”值。在这种情况下,这是一种很好的做法

计算 按钮计算

以及使用方法的原因是什么?看起来计算属性更好(假设我们正在谈论“获取”方法)......
2021-03-15 13:47:13
@Bsinn 这是一个很好的问题:原因是基本上 Vue 不知道根据更新的内容需要运行哪一种方法。这就是计算属性所做的操作,它们观察需要计算或重新计算的变量,并且只在需要时运行。
2021-04-02 13:47:13
为什么按下 1 个按钮时所有方法都会执行?原因/逻辑是什么?
2021-04-04 13:47:13
@user3529607 据我所知,方法在挂载或创建 vue 实例时很有用。计算属性无法做到这一点。此外,我们必须返回计算属性的值。
2021-04-05 13:47:13
@ user3529607 但计算属性不接收参数。
2021-04-07 13:47:13

这是这个问题的细分。

何时使用方法

  • 对 DOM 中发生的某些事件做出react
  • 在组件中发生某些事情时调用函数。
  • 您可以从计算属性或观察者调用方法。

何时使用计算属性

  • 您需要从现有数据源组合新数据
  • 您在模板中使用了一个由一个或多个数据属性构建的变量
  • 您希望将复杂的嵌套属性名称简化为更易读且易于使用的名称(但在原始属性更改时更新它)
  • 您需要从模板中引用一个值。在这种情况下,创建计算属性是最好的选择,因为它是缓存的。
  • 您需要监听多个数据属性的变化
很清楚,我在找什么。大多数答案解释了为什么计算值很好,但我知道这一点。我实际上是在寻找如果计算如此之好,为什么您甚至想要使用方法。这至少解释了其中的一部分。
2021-03-22 13:47:13
清楚和最好的答案。谢谢迭戈
2021-04-02 13:47:13

来自 docs

..计算属性根据它们的依赖关系进行缓存。计算属性只会在其某些依赖项发生更改时重新评估。

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

@gleenk 我将添加一个实际示例,向您展示方法和计算属性之间的缓存/依赖项差异。我希望你会欣赏它。
2021-03-16 13:47:13
谢谢@GiulioBambini
2021-03-25 13:47:13
嗨,你能写一个有用的例子来展示实际使用的差异吗?
2021-04-06 13:47:13

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

计算

在第一次执行时,函数内的代码将被执行,vuejs 会将计数器值存储在缓存中(以便更快地访问)。但是当我们再次调用该函数时,vuejs 将不会再次执行该函数内部编写的代码。它首先检查对计数器所做的任何更改。如果进行了任何更改,那么它只会重新执行该函数内的代码。如果没有对计数器进行任何更改,vuejs 将不会再次执行该函数。它将简单地从缓存中返回先前的结果。

方法

这就像javascript中的普通方法一样。每当我们调用该方法时,它总是会执行函数内部的代码,而不管对计数器所做的更改。

无论代码如何更改,方法都会始终重新执行代码。只有当它的依赖值之一发生变化时,计算才会重新执行代码。否则它会在不重新执行的情况下为我们提供缓存中的先前结果