vue 系列 -- computed,methods,watch 的区别

450 阅读2分钟

使用方法

computed

目的:计算属性

示例

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4

注意: 计算属性的结果会被缓存,计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 a 的值没有发生改变,多次访问 aDoubleaPlus 计算属性都会立即返回之前的计算结果,而不必再次执行函数

由于 Date.now() 不是响应式依赖,每当触发重新渲染时,调用方法将总会再次执行函数 now:

computed: {
  now: function () {
    return Date.now()
  }
}
vm.now // 1630998859578,每次都打印出不同结果
vm.now // 1630998863217

缓存计算结果的意义 在于:假设我们有一个性能开销比较大的计算属性 A,它需要 遍历一个巨大的数组 并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter

methods

目的:制作事件处理器,处理众多事件

示例

var vm = new Vue({
  data: { a: 1 },
  methods: {
    plus: function () {
      this.a++
    }
  }
})
vm.plus()
vm.a // 2

watch

示例

var vm = new Vue({
  data: {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: {
      f: {
        g: 5
      }
    }
  },
  watch: {
    a: function (val, oldVal) { // 1.两个参数:新值、老值
      console.log('new: %s, old: %s', val, oldVal)
    },
    b: 'someMethod', // 方法名
    c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true // 2.指定该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
    },
    d: {
      handler: 'someMethod',
      immediate: true // 3.指定该回调将会在侦听开始之后被立即调用
    },
    // 4.传入回调数组,它们会被逐一调用
    e: [
      'handle1',
      function handle2 (val, oldVal) { /* ... */ },
      {
        handler: function handle3 (val, oldVal) { /* ... */ },
        /* ... */
      }
    ],
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }
})
vm.a = 2 // => new: 2, old: 1

computed vs methods

  • computed 里的函数会缓存计算结果;
  • methods 里的函数如果用于计算的话将不会缓存计算结果,每次调用时都会执行

computed vs watch

  • computed 只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。
  • watch 每次都需要执行函数。watch 更适用于 数据变化时的异步操作

参考文章