Vue笔记:区别methods、 computed 和 watch

2,048 阅读3分钟

在Vue中,methods、 computed 和 watch 都可以呈现类似的最终效果,甚至将同一个函数定义为methods、 computed 和 watch,那么它们有什么区别呢?

1. 从性质上看

methods是定义在vue实例里的函数,需要手动调用。

类型: { [key: string]: Function }

methods对象中,键是函数名称,值是对应的函数。


computed是计算属性,在取用时与data对象里的数据属性方式相同。

类型: { [key: string]: Function | { get: Function, set: Function } }

computed对象中,键是函数名称,值是对应的函数表达式。

使用 get 与 set 实现双向绑定。


watch是监听属性,在取用时与data对象里的数据属性方式相同。但watch调用的函数是回调函数。

类型: { [key: string]: string | Function | Object }

watch对象中,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

ps:watch虽然可以监听到对象的变化,但是无法监听到具体对象里面那个属性的变化。

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
  //当firstName发生改变之后,firstName对应的函数才会被调用
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

2. 从作用机制上看

methods中保存着vue实例的函数,在使用时需要手动调用才能执行

<!-- 在模板中调用 -->
<p>Reversed message: "{{ reversedMessage() }}"</p>
<button v-on:click="doThis()"></button>

<!-- 或者直接使用函数名 -->
<button v-on:click="doThis"></button>

另外,手动调用也意味着我们可以传参,以及事件对象。

<!-- 直接使用函数名调用时,会默认将第一个参数作为事件对象 $event -->
<!-- 调用函数传参时,事件对象 $event 必须作为最后一个参数显式传递-->
<button v-on:click="say("Hi",$event)"></button>

watch和computed是调用属性,将自动调用相关函数,不需要手动调用。

<!-- 在模板中调用时不需要 "()" -->
<p>Reversed message: "{{ reversedMessage }}"</p>

为watch和computed都以Vue的依赖追踪机制为基础,当某个数据发生变化时,所有依赖这个数据的“相关”数据“自动”发生变化,即自动调用相关函数。

在下面的例子中,computed属性调用的computedDate函数,data中不存在依赖值,所以只会返回一次new Date值,因为computed的依赖值并未发生改变,而computed只会提供缓存的值(多次调用不会变化),但是methods会不断被调用

new Vue({
            el: '#app',
            methods: {
                getMethodsDate: function () {
                    alert(new Date())
                },
                // 返回computed选项中设置的计算属性——computedDate
                getComputedDate: function () {
                    alert(this.computedDate)
                }
            },
            computed: {
                computedDate: function () {
                    return new Date()
                }
             }
        })

3. 从使用场景上看

methods、 computed 和 watch 对应不同的使用场景:

  • methods适用于各类场景,因为它不处理数据逻辑关系,只提供可调用的函数
  • computed适用于“一个数据受多个数据影响”的使用场景
  • watched适用于“一个数据影响多个数据”的使用场景

computed的使用场景:一个数据受多个数据影响

当我们需要对data进行转化(感觉有点像excel的数据透视图),并且依赖于其它数据时,应该使用 computed,因为只有 computed 依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。利用 computed 的缓存特性,避免每次获取值时,都要重新计算。

watch的使用场景:一个数据影响多个数据

当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。