watch 和 computed 的区别和运用场景
- watch: 是监听属性值的变化,是在数据变化时,要执行异步和开销较大的操作时使用,即一个属性影响多条数据时使用
- 使用 watch 我们可以执行异步操作,并最终得到我们想要的值
data(){ return { name:'你好' } } watch:{ /* 原有写法 */ name(newval,oldval){ conslog.log(newval,'新的值') conslog.log(oldval,'旧的值') } }
- 如果想要其在最初绑定的时候就去执行的话,可以换一种写法,
我们给属性绑定一个 handler 方法,当然我们没这样写的话,默认也是有 handler 方法的,
然后再添加:immediate:true,告诉 watch 我们给 name 绑定了一个 handler 方法,并且在 watch 声明了 name 之后,就立即执行 handler 方法,如果 immediate:false 时,就和原有写法一样了,不会在绑定时就去执行data(){ return { name:'你好' } } watch:{ name:{ handler(newval,oldval){ conslog.log(newval,'新的值') conslog.log(oldval,'旧的值') }, immediate:true,//代表watch声明了name属性之后立马执行handler方法 } }
- 但当我们给监听的对象添加一个值或者是删除一个值的时候,你会发现 vue 并没有什么变化,这是因为 vue 只会对初始实例化时,在 vue 上的 属性才能实现双向绑定,因为 vue 的本质也还是 JavaScript 的限制,不能监测到在实例化时未被 getter/settter 转换的值
这是就算我们对 name 这个对象进行监听了,也不会造成数据变化视图更新,这是我们就要使用 watch 对对象的深度监听了,deep:truedata(){ return { obj:{ name:'你好' } } } watch:{ obj:{ handler(newval,oldval){ conslog.log(newval,'新的值') conslog.log(oldval,'旧的值') }, immediate:true,//代表watch声明了name属性之后立马执行handler方法 deep:true//可以深度监测到obj对象的属性值变化 } }
- 但这样的话,deep 等于说是进行深入观察了,一层层的往下查找,给每一个属性都添加一个监听事件,这样性能的开销就大了
当对象属性较多时,每个属性值的变化都会执行 handler。如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性,这样就不用使用深度监听给每一个对象属性都添加监听事件了,只有 vue 一层层解析,知道遇到要监听属性name
时,才给属性name
添加监听函数data(){ return { obj:{ name:'你好' } } } watch:{ 'obj.name':{ handler(newval,oldval){ conslog.log(newval,'新的值') conslog.log(oldval,'旧的值') }, immediate:true,//代表watch声明了name属性之后立马执行handler方法 } }
- 使用 watch 我们可以执行异步操作,并最终得到我们想要的值
- computed:当一个业务逻辑或者是一个属性,在他所依赖的值变化时也要发生变化时使用,即一个属性受多个属性影响时使用
- computed 是带有缓存的,我们计算某个值的变化时,会将变化的值存储起来
- compiuted 函数必须要用 return 返回结果,和在 methods 使用差不多
- 不过使用 computed 时,性能开销会比较小一些,因为只有所依赖的值发生变化时,其才会重新计算,然后缓存
data(){ return { name:'你好' } } computed:{ name(){ return 'nihao' } }
- 也给将数据给拆开来使用,不过组合简单,拆开就有点复杂了
data(){ return { name:'你好', name1:'你好', name2:'你好', } } computed:{ name(){ set(){ return 'nihao' }, get(name) const names = name.split('h') this.name1 = names[0] this.name2 = names[1] } }