阅读 70

《 computed 和 watch 的区别》

computed

computed 是计算属性 是可以通过计算得出的属性. 计算属性可以是一个函数,也可以是getter和setter组成的对象

好处: 在调用时不用加括号,可以直接使用,根据依赖可以缓存,在依赖不变时 computed 不用在重新计算

import Vue from "vue/dist/vue.js";

new Vue({
 data: {
  name: '亚索',
   age: '18'
 },
 computed: {
   newName() {
     return this.name + ' ' + this.age      
   }
 },
 template: `
   <div>
     {{newName}}
   </div>
 `,
 methods: {}
}).$mount("#app");
复制代码

newName通过this.name + this.age 计算得出,newName使用时不需要加括号,可以直接作为属性使用,展示再页面中


使用 get 和 set 还可以实现改名字

import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
  new Vue({
    data: {
     user: {
          name: "亚索", 
     }
    },
      computed: {
          displayName: {
              get() {
               const user = this.user;
               return user.name ;
       },
        set(value) {
            console.log(value);
           this.user.name = value;
        }
       }
     },
         template: `
          <div>
                {{displayName}}
         <div>
              <button @click="add">改名字</button>
        </div>
        </div>
        `,
         methods: {
         add() {
             console.log("add");
             this.displayName = "盲仔";
        }
       }
     }).$mount("#app");
复制代码

通过 setter 和 getter 使得计算属性可修改,点击‘改名字’时,计算结果发生变化,重新运行计算,进行页面更新。计算属性的结果会被缓存,计算属性只有在它的相关依赖发生改变时才会重新计算。 所以再次点击‘改名字’由于计算结果不变,不会重新运行计算。


watch 监听/侦察

  • 当数据变化时执行一个函数
  • watch属性可以是字符串、函数、对象、数组
  • 拥有deep,immediate两属性

deep 如果要监听一个对象是否需要监听里面的一个选项,可以使用 deep:truedeep:false immediate 表示第一次要执行时,是否要执行这个函数.可以使用 immediate:trueimmediate:false

// 引用完整版 Vue,方便讲解
import Vue from "vue/dist/vue.js";

new Vue({
  data: {
    n: 0,
    obj: {
      a: "a"
    }
  },
  template: `
    <div>
      <button @click="n += 1">n+1</button>
      <button @click="obj.a += 'hi'">obj.a + 'hi'</button>
      <button @click="obj = {a:'a'}">obj = 新对象</button>
    </div>
  `,
  watch: {
    n() {
      console.log("n 变了");
    },
    obj() {
      console.log("obj 变了");
    },
    "obj.a": function() {
      console.log("obj.a 变了");
    }
  }
}).$mount("#app");
复制代码

这时候

  • 点击n+1 : 打印出“n 变了”
  • 不点击obj.a + 'hi' , 点击obj = 新对象 : 打印出"obj 变了",不打印"obj.a 变了"
  • 点击obj.a + 'hi' : 打印出“obj.a 变了”,不打印"obj 变了"

说明watch的监听方式是:简单数据类型看值,复杂数据类型(对象)看地址

也可以使用 deep 监听 obj 的变化

watch: {
    n() {
      console.log("n 变了")
    },
    obj() {
      console.log("obj 变了")
      deep: ture       // 可以监听到obj对象的所有内部属性
    },
    "obj.a": function() {
      console.log("obj.a 变了")
    }
  }
复制代码
  • 点击obj.a + 'hi' : 打印出“obj.a 变了”和 "obj 变了"
  • 当deep:true 会监听到obj对象的所有内部属性,默认值为false

immediate属性

    import Vue from "vue/dist/vue.js";
     new Vue({
      data: {
       name: '亚索',
       fullName: ''
     },
      watch: {
         name: {
         handler: 'change'
    }
},
      template: `
       <div>
          {{fullName}}
          <button @click="name='盲仔'">改名字</button>
      </div>
       `,
         methods: {
         change() {
       this.fullName = this.name
      }
     }
    }).$mount("#app");
复制代码
  • 通过 fullName 属性展示 name 的计算值
  • 运行上面代码,页面啥也没有
  • 然后点击“改名字”,页面显示 "盲仔"
  • 但是页面刚开始时,name 的值 "亚索" 是不显示的,因为watch不会监听第一次变化
watch: {
    name: {
      handler: 'change',
      immediate: true
    }
}
复制代码
  • 改造一下初始页面展示 "亚索"

  • 当 immediate:true 时,回调函数会在监听开始后立刻执行,可以监听到到第一次变化


总结 computed 和 watch 的区别区别

  • computed 是用来计算一个值的,使用时不需要加括号,可以直接当属性使用。computed 拥有依赖缓存特性,如果依赖值不变,computed不会重新计算

  • watch 是用来监听的,有两个选项,immediate 和 deep,当immediate: true时,表示会在第一次运行是执行这个函数,当 deep:true时,如果监听一个对象,会同时监听其内部属性。watch没有依赖缓存特性。


学习小计,有错误请指正
文章分类
前端
文章标签