计算属性和监视属性
目录1. 计算属性
-
定义:使用的属性起初并不存在,要通过已有属性计算得来,这样的属性称作计算属性。
- 计算属性以对象形式定义,需要在内部配置get和set方法
- get函数会在初次读取时执行一次,当依赖的数据发生改变时会被再次调用
- set函数会在计算属性被修改时执行。如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生(如果之后确定不需要修改计算属性,可以省略set)
- 计算属性以对象形式定义,需要在内部配置get和set方法
-
原理:底层借助了Object.defineproperty方法提供的getter和setter
-
与methods实现相比,内部有缓存机制以供复用,效率更高,调试方便
计算属性最终会出现在vm上,直接读取使用即可
<div id="root"> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div>
<div id="root"> 姓: <input type="text" v-model="firstName"> <br/><br/> 名: <input type="text" v-model="lastName"> <br/><br/> 全名: <span>{{fullName}}</span> </div> <script> new Vue({ el:'#root', data:{ firstName:'张', lastName:'三' }, computed:{ fullName:{ get(){ //此处this指向vm return this.firstName + '-' + this.lastName; }, set(value){ const arr = value.split('-') this.firstName = arr[0] this.lastName = arr[1] } } } }) </script>
-
简写形式
由于计算属性一般不需要获取,所以可以不设置setter函数,那么可以直接用属性名作为函数名
computed:{ fullName(){ return this.firstName + '-' this.lastName } }
2. 监视属性
-
定义:如果需要监控数据的变动,可以设置监视属性。当被监视的属性变化时,回调函数自动调用,进行相关操作
-
监视的属性必须存在,才能进行监视
-
监视的两种写法:
- new Vue时传入watch配置(适用于已确定的需要监视的属性)
- 通过vm.$watch监视(适用于动态设置需要监视的属性)
<div id="root"> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button> </div>
<script> new Vue({ el:'#root', data:{ isHot:true }, method{ changeWeather(){ this.isHot = !this.isHot } }, computed:{ info(){ return this.isHot ? '炎热' : '凉爽' } }, watch:{ //当isHot属性被改变,调用回调函数handler 'isHot':{ immediate:true, //初始化时让handler调用一次,默认为false handler(newVal,oldVal){ console.log('isHot被修改',newVal,oldVal) } } } }) /* 写法二: vm.$watch('isHot',{ immediate:true, handler(newVal,oldVal){ console.log('isHot被修改',newVal,oldVal) } }) */ </script>
2.1 深度监视
-
Vue中的watch默认不监测对象内部值的改变(一层)
配置deep:true可以监测对象内部值改变(多层)
-
Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
使用watch时根据数据的具体结构,决定是否使用深度监视
<script> new Vue({ el:'#root', data:{ numbers:{ a:1, b:1 } }, watch:{ 'numbers':{ deep:true, handler(){ console.log('numbers改变了') } } } }) </script>
-
简写形式
如果不需要对监视属性做额外配置(如immediate,deep)则可以直接简写
watch:{ isHot()(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } }
3. computed和watch对比
-
computed能完成的功能,watch都能完成
watch能完成的功能,computed不一定能完成(如异步操作)
但介于computed比watch方便得多,所以优先使用computed
-
在异步操作中computed和watch的区别
需求:将属性延迟1秒显示在页面上
- watch:可以正常实现需求,因为watch不依赖return,而是直接修改数据
watch:{ firstName(val){ setTimeout(() => { this.fullName = val + '-' + this.lastName },1000) } }
- computed:无法实现需求,因为computed依赖return来返回数据,而异步操作无法实现这点
computed:{ firstName(){ setTimeout(() => { //这样只会return到setTimeout函数里去 return this.fullName + '-' + this.lastName },1000) } }