Vue:computed和watch

112 阅读1分钟

一、高级属性computed

1、computed-计算属性

  • 依赖其他属性计算而来的属性就是计算属性,可直接使用
new Vue({
  data:{
    user:{
      nickname:"蓝蓝"
      ...
    }
  },
  computed:{
    displayName:{
      get(){
        const user=this.user;
        return user.nickname||...;
      },
      set(value){
        this.user.nickname=value
      }
    }
  },
  template:`
    <div>
      {{displayName}}  //直接使用
      <button @click="add">set</button>
    </div>
  `,
  methods:{
    add(){
      this.displayName="jack"  //直接使用
    }
  }
}).$mount("#app")
  • 如果以赖的属性没有变化,就不会重新计算

二、高级属性watch

1、watch-监听

  • 监听某个数据,当其发生变化时,执行一个函数
new Vue({
  data:{
    n:0;
    history:[]
  },
  watch:{
    n:function(newValue,oldValue){
      this.history.push({from:oldValue,to:newValue})
    }
  },
  template:`
    ...
  `,
  methods:{
    ...
  },
}).$mount("#app")

2、watch是异步的

  • 需求:增加一个撤销按钮,点击时不执行watch里的函数(即不记录新老数据变化)
new Vue({
  data:{
    n:0;
    history:[]
    inUndoMode:false  //是否处在撤销模式,false为在
  },
  watch:{
    n:function(newValue,oldValue){
      if(!this.inUndoMode){
        this.history.push({from:oldValue,to:newValue})
      }
    }
  },
  template:`
    ...
    <button @click="undo">撤销</button>
  `,
  methods:{
    ...
    undo(){
      const last=this.history.pop();
      this.inUndoMode=true;
      const old=last.from;
      this.n=old;  //watch是异步的,当以下代码都执行完后再执行watch
      this.$nextTick(()=>{  //等一会儿再变,类似setTimeout
        this.inUndoMode=false
      })
    }
  },
}).$mount("#app")

3、理解变化

data:{
  n:0,
  obj:{
    a:"a"
  }
}
  • 操作n+1,那么n变了
  • 操作obj.a+'hi',那么obj.a变了,obj没变
  • 操作obj:{a:'a'},那么obj变了,obj.a没变
  • 总结:简单类型看值,复杂类型(如对象)看地址,其实就是===的规则

4、deep:true

  • 需求:操作obj.a+'hi',那么obj.a变了,obj也变了
  • 原来watch只是watch:{...obj(){}},需改为
new Vue({
  data:{
    ...
  },
  template:`
    ...
  `,
  watch:{
    obj:{
      handler(){
        console.log("obj.a变了");
        console.log("obj也变了")
      },
      deep:true  //监听obj时是否往深了看
    }
  }
}).$mount("#app")

5、watch语法

5.1、常规语法
  • {[key:string]:String|Function|Object|Array}
  • watch:{n:()=>{this.xxx}}错误,watch里面不能用箭头函数,这里的this是全局变量了
  1. n:function(){},用普通函数,这里的this就是vm
  2. o2:function(value,oldvalue){},这两个值是vue传的
  3. o3(){},ES6写法,是2. 的缩写
  4. o4:[f1,f2],注意,也不能是箭头函数
  5. o5:'methodName',去methods里找对应函数
  6. o6:{handler:fn,deep:true,immediate:true},'object.a':function(){},immediate-第一次是否执行
5.2、非常规语法(尽量不用)
  • vm.$watch('xxx',fn,{deep:...,immediate:...}),'xxx'可以改为一个返回字符串的函数,该写法用在vue外面
  • 如果想写在vue里,可以写在钩子里created(){this.$watch...}

三、总结:computed和watch的区别

  • computed是计算属性,可直接当属性用,依赖不变时不会重复计算,即不会重复缓存
  • watch是监听,某属性变化时,执行一个函数,有两个选项,immediate(第一次是否执行)和deep(监听时是否往深了看)