2020-05-27 Vue中computed,watch,methods

545 阅读2分钟

先贴一下官方译名:

computed:计算属性

watch:侦听属性

methods:方法

<template>
  <div id="calTest">
    {{num}}
    {{num1()}}
    {{msg}}
    <button @click="changeMsg">change msg</button>
    <button @click="changeName">change name</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: "betty",
      msg: 100
    };
  },
  computed: {
    num() {
      let res = this.name + "!";
      console.log("do computed");
      return res;
    }
  },
  methods: {
    num1() {
      let res = this.name + "!";
      console.log("do methods");
      return res;
    },
    changeMsg() {
      this.msg += 1;
    },

    changeName() {
      this.name = "alan";
    }
  }
};
</script>

这是一个 computed 和 methods 比较使用的例子,我们可以很清楚的看到相似与不同:

相同之处就是用 computed 和 methods 返回的结果都是一样的

不同在于,在模板中computed 直接作为变量调用,而 methods写成方法调用(即加上括号);

再有,例子中的 msg 是一个独立的数据,用一个button控制值的改变,这么做是为了看出 computed 和 methods 的关键性差别:

computed 有缓存,只有依赖数据变化才重新计算,而 methods 在每次视图渲染时都会执行。当我们点击 changeMsg 按钮时,computed是不会执行的,而methods 的 num1 方法会执行,只有我们在点击 changeName 按钮时(即num的依赖数据name的值发生了改变),computed 会执行(当然methods num1也会执行)

<script>
export default {
  data() {
    return {
      a: 1,
      b: 2,
      c: { c1: 6 },
      d: 4,
      e: {
        f: {
          g: 5
        }
      }
    };
  },
  watch: {
    a: function(val, oldVal) {
      console.log(val, oldVal);
    },
    b: "someMethod",
    c: {
      handler: function(val, oldVal) {
        console.log(val, oldVal);
      },
      deep: true
    },
    d: {
      handler: "someMethod",
      immediate: true
    },
    "e.f": function(val, oldVal) {
      console.log(val, oldVal);
    }
  },
  methods: {
    someMethod() {
        console.log("somemethods");
    }
  }
};
</script>

c 如果不加 deep 的话,c1 的值变动的时候是监听不到的,加了 deep 无论嵌套多深都能监听,val 和 oldVal 都是返回 {ob: Observer} 对象

d 回调会在侦听开始之后被立即调用

e.f 也是返回 {ob: Observer} 对象,这里要注意一点,在用 Vue Devtools 修改 c 和 e.f 的值的时候,不要去修改c1 / g 的值,而是要修改 c 和 e.f 的值,否则会出现 val 和 oldVal 都是新值的情况

可以看到,watch 里的对象,key是需要侦听的数据的名字,value是回调函数/方法名...

注意:watch的回调函数不要用箭头函数


那么,computed 和 watch 的区别又是什么呢?

其实官方文档已经很好地把二者适用的场景描述了出来:

computed : 减少模板中的逻辑,快速计算更新视图中的值

watch : 虽然在大多数的情况下computed更合适,但有时也需要一个自定义的侦听器。在数据变化时执行异步操作或者开销比较大的操作时,用watch