1. computed

计算属性是有缓存的,只有在依赖的属性变化时才重新计算,否则就一直用之前缓存的值。如果不想缓存,可以写成方法调用的方式。详见 计算属性缓存 VS 方法

computed 即计算的意思,是创建 vue实例 中的计算属性,属性值为一个对象,对象里面是各种计算得来的数据变量,和 data 属性里面的变量一样

也就是说该属性用于存放计算得来的各种属性,并且如果该计算属性依赖的属性没有发生变化就不会重新触发计算。

以下小例来自 vue 官网

  1. var vm = new Vue({
  2. data: { a: 1 },
  3. computed: {
  4. // 仅读取
  5. aDouble: function () {
  6. return this.a * 2
  7. },
  8. // 读取和设置
  9. aPlus: {
  10. get: function () {
  11. return this.a + 1
  12. },
  13. set: function (v) {
  14. this.a = v - 1
  15. }
  16. }
  17. }
  18. })
  19. vm.aPlus // => 2
  20. vm.aPlus = 3
  21. vm.a // => 2
  22. vm.aDouble // => 4 是属性调用,不是函数调用

2. watch

watche 即监听的意思,是对 data 属性中的各种数据进行监听的,会在监听的数据发生变化时自动调用对应的监听函数,因此监听的属性是 data 里的数据,属性值是相关的操作。如下所示:

  1. new Vue({
  2. data: {
  3. n: 1,
  4. obj: {
  5. a: "a"
  6. },
  7. e: 2
  8. },
  9. watch:{
  10. n: function (newVal, oldVal) {
  11. console.log(`a变化了,由${oldVal}变成了${newVal}`)
  12. },
  13. obj() {
  14. console.log("obj 变了");
  15. },
  16. "obj.a": function() {
  17. console.log("obj.a 变了");
  18. },//属性名有特殊符号 . 因此必须用引号括起来
  19. e: [
  20. 'handle1',
  21. function handle2 (val, oldVal){
  22. /do something
  23. }
  24. ] //数组的放置依次执行多个函数操作
  25. }
  26. })

immediate: true

watch 里面的函数是只有在数据变化时才会被自动调用,因此在数据初始化刚开始出现在页面时是不会执行 watch 里的监听回调的,因此若想在数据在初始化时就立即被调用,则要自行设置如下:

  1. new Vue({
  2. data:{
  3. c: 4
  4. },
  5. watch:{
  6. handler: 'someMethod', //处理函数可以是 methods 里的方法名
  7. immediate: true //将这一个属性设置为 true,表示立即调用
  8. }
  9. })

deep: true

当一个对象的内部属性发生变化时,默认该属性不会被认为发生变化,因为用到是 === 操作符来判断的是否改变,而对象内部数据改变但地址没有改变,因此在比较仅改变对象内部数据时前后对象是比较的地址,结果是 obj 没有改变,就只会调用内部属性的监听函数,而不会调用其所在对象的监听函数,如下所示:

  1. new Vue({
  2. data: {
  3. obj: {
  4. a: "a"
  5. }
  6. },
  7. watch:{
  8. obj() {
  9. console.log("obj 变了");
  10. },
  11. "obj.a": function() {
  12. console.log("obj.a 变了");
  13. },//属性名有特殊符号 . 因此必须用引号括起来
  14. },
  15. template: `
  16. <div>
  17. //按钮点击只会输出 obj.a 变了,而不会输出 obj 变了
  18. <button @click="obj.a += 'hi'">obj.a + 'hi'</button>
  19. //由于改变了整个对象,整个对象里面的都会被改变,输出 obj.a 变了,obj 变了
  20. <button @click="obj = {a:'a'}">obj = 新对象</button>
  21. </div>
  22. `
  23. })

因此若想当对象内如数据改变时认为对象也改变了,触发对象的监听函数,则可在对象的监听事件中加上一句 deep: true ,表示往深了看,用于复杂类型的深度监听,用如下方法:

  1. watch:{
  2. obj: {
  3. handler:function(){
  4. console.log("obj 变了");
  5. },
  6. deep: true //默认是 false
  7. }
  8. }

3. 二者的区别

3.1 分别是什么

computed 是计算属性,是 data 属性的扩展,用于存放基于 data 数据经过各种计算得来的属性,有依赖,有缓存,当其所依赖的数据发生变化时 computed 会重新计算

watch 是监听属性,是对 data 中各种数据的监听,在数据变化时做出相应处理。

3.2 调用过程

computed 是会产生新的数据属性,并对其进行监听计算。

watch 只是单纯地对当前数据进行监听处理,不会产生新的数据属性。