Vue Computed中get和set的用法及Computed与watch的区别
作者:前端程序猿微凉
vue的computed方法
vue.js的computed方法
计算属性是基于它们的依赖进行缓存的,只在相关依赖发生改变时它们才会重新求值。
用 methods 也可以实现同样的效果,但 methods 在重新渲染的时候会重新调用执行,在性能上 computed 优于 methods,当不需要缓存时可用 methods。
computed回调函数域中的回调函数方法可以在插值表达式{{}}中直接获取返回结果而无需在data数据域中定义相关的属性,这一点相较于watch中而言使用起来也更方便些。
get
一般情况下,我们只是使用了computer中的gettter属性,默认只有 getter,我们只是单纯的使用了gettter属性。
set
只有当computed监测的值变化的时候,set才回被调用。
computed中get和set的栗子(引用官网)
var vm = new Vue({ data: { a: 1 }, computed: { // 仅读取 aDouble: function () { return this.a * 2 }, // 读取和设置 aPlus: { // 页面初始化时会先执行一次 get 好比与computed的getter属性 // 监视 data 中 a 的属性值,只有发生改变时,它们才会重新求值,否则取缓存中的 get: function () { console.log('调用了getter属性') return this.a + 1 }, // 监视当前属性值的变化,当属性值发生变化时执行, // 更新相关的属性数据,类似于 watch 的功能 set: function (newValue) { console.log('调用了settter属性') console.log(newValue,'newValue'); this.a = newValue - 1 } } } }) vm.aPlus // => 2 console.log(vm.aPlus,'第一次执行的vm.aPlus'); // DOM 还没更新 console.log(vm.a,'第一次vm.a'); // 当监听到值变化时 执行set vm.aPlus = 4 console.log(vm.aPlus,'第二次执行的vm.aPlus'); console.log(vm.a,'第二次vm.a'); // vm.$nextTick方法 将回调延迟到下次 DOM 更新循环之后执行。 // 在修改数据之后立即使用它,然后等待 DOM 更新。 // 它跟全局方法 Vue.nextTick 一样,不同的是回调的this自动绑定到调用它的实例上。 vm.$nextTick(function () { // DOM 现在更新了 console.log(vm.a,'this.vm.a'); }) // 更新后data中a为3 vm.aDouble // => 6 console.log(vm.a,'vm.aDouble中的a',vm.aDouble,'vm.aDouble');
可以看打印结果
watch 方法
1.通过 watch 监听 data 数据的变化,数据发生变化时,就会打印当前的值
watch: { data(val, value) { console.log(val) console.log(value) } }
2.通过 watch 监听 list 数据的变化,数据发生变化时,this.number++(使用深度监听)
data() { return { list: { 'id': 1, 'type': 0 }, number: 0 } }, watch: { list: { handler(newVal) { this.number++ }, deep: true } }
3. 通过 watch 监听 data 数据的变化,数据发生变化时,执行 change 方法
watch: { data: 'change' // 值可以为methods的方法名 }, methods: { change(curVal,oldVal){ console.log(curVal,oldVal) } }
watch中的immediate、handler和deep属性
1. immediate 和 handler
这样使用watch时有一个特点,就是当值第一次绑定时,不会执行监听函数,只有值发生改变时才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
data() { return { list: { 'id': 1, 'type': 0 }, number: 0 } }, watch: { list: { handler(newVal) { this.number++ }, immediate: true } }
2. deep
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,此时就需要deep属性对对象进行深度监听。
data() { return { list: { 'id': 1, 'type': 0 }, number: 0 } }, watch: { list: { handler(newVal) { this.number++ }, deep: true } }
设置deep:true则可以监听到 list.id 的变化,此时会给 list 的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行 handler。
如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性:
data() { return { list: { 'id': 1, 'type': 0 } } }, watch: { 'list.id': { handler(newVal, oldVal) { ...... }, deep: true } }
结论:数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。
computed与watch的区别
computed与watch的不同点
触发条件不同
- computed计算属性会依赖于使用它的data属性,只要是依赖的data属性值有变动,则自定义重新调用计算属性执行一次。
- watch则是在监控的data属性值发生变动时,其会自动调用watch回调函数。
执行速度不同
- computed计算属性的值是直接从缓存中获取,而不是重新编译执行一次,因而其性能要高一些,尤其是在data属性中的值无变化,而重复调用computed回调函数时更是如此,所以说在Vue中,应该尽可能的多使用computed替代watch。
- watch中的值需要data属性重新编译执行,因而其性能方面会有所损失。
使用方式不同
- computed计算属性的回调函数方法可以直接在页面中通过插值表达式——{{}}来获取。此时我们不需要再data数据域中再定义一个与方法名相同的属性。
- watch中的方法名必须是data数据域中所存在的,否则无法使用。
相同点
都可以实现通过监控data数据域中属性值的变化来触发相应的回调函数,进而实现我们特殊的逻辑业务处理功能。
项目中的使用总结
1.在methods中,对于data中在视图中需要的任一个数据发生变化,都会重新更新视图,不会缓存数据。
2.在computed中,计算过后会有缓存结果,下次调用时候,直接取缓存的结果,除非所依赖的响应式数据发生变化才会再次执行,计算内部一定有return。(在用的时候直接写函数名字)
当一个属性受多个属性影响的时候就需要用到computed 最典型的栗子:购物车商品结算的时候
3.监听指定的响应式数据发生变化,如果有变化会重新调用。
当一条数据影响多条数据的时候就需要用watch 栗子:搜索数据
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。