一、计算属性
- 定义:要用的属性不存在,要通过已有属性计算得来。 例如:已知姓和名,求全名。
- 原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
<div id="root"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{fullName}}</span> <br/><br/> </div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 const vm = new Vue({ el:'#root', data:{ firstName:'张', lastName:'三', }, computed:{ fullName:{ //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。 get(){ console.log('get被调用了') return this.firstName + '-' + this.lastName }, //set什么时候调用? 当fullName被修改时。 set(value){ console.log('set',value) const arr = value.split('-') this.firstName = arr[0] this.lastName = arr[1] } } } }) </script>
- 优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
- 备注: (1)计算属性最终会出现在vm上,直接读取使用即可。 (2)如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
-
简写形式
computed:{ fullName(){ console.log('get被调用了') return this.firstName + '-' + this.lastName } }
备注(使用场景):当不需要set()改变依赖数据时可以使用简写形式,调用方式不变。
二、监视属性(watch)
- 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
- 监视的属性必须存在,才能进行监视!!
-
监视的两种写法:
(1)new Vue时传入watch配置
使用: <h2>今天天气很{{info}}</h2> 定义: watch:{ isHot:{ immediate:true, //初始化时让handler调用一下 //handler什么时候调用?当isHot发生改变时,可以监控到变化以及变化前后的值 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } } }
(2)通过vm.$watch监视定义在vue外面的 vm.$watch('isHot',{ immediate:true, //初始化时让handler调用一下 //handler什么时候调用?当isHot发生改变时。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } })
-
深度监视
(1)Vue中的watch默认不监测对象内部值的改变(一层)。
(2)配置deep:true可以监测对象内部值改变(多层)。
numbers:{ deep:true, handler(){ console.log('numbers改变了') } }
-
监视属性简写:
(1)new Vue时传入watch配置简写:
isHot(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue,this) }
备注(使用场景):当不需要immediate和deep时可以使用
(2)通过vm.$watch监视简写:vm.$watch('isHot',(newValue,oldValue)=>{ console.log('isHot被修改了',newValue,oldValue) })
备注(使用场景):当不需要immediate和deep时可以使用
三、computed和watch之间的区别:
- computed能完成的功能,watch都可以完成。
- watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
watch:{ firstName(val){ setTimeout(()=>{ //为什么用箭头函数:如果不用箭头函数,this指向的将是window,因为setTimeout是window的方法;写成箭头函数,这样this的指向才是vm 或 组件实例对象。
console.log(this) this.fullName = val + '-' + this.lastName },1000); }, lastName(val){ this.fullName = this.firstName + '-' + val } }
备注:
(1)所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
(2)所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。