Vue中計(jì)算屬性和監(jiān)視屬性
計(jì)算屬性
1.定義:要用的屬性不存在,要通過(guò)已有的屬性計(jì)算得來(lái)
2.原理:底層借助了Object.defineproperty方法提供的getter和setter
3.getter函數(shù)什么執(zhí)行?
(1)初次讀取時(shí)會(huì)執(zhí)行一次
(2)當(dāng)依賴(lài)的數(shù)據(jù)發(fā)生改變時(shí)會(huì)被再次調(diào)用
4.優(yōu)勢(shì):與methods實(shí)現(xiàn)相比,內(nèi)部有緩存機(jī)制(復(fù)用),效率更高,調(diào)試方便
5.備注:
(1)計(jì)算屬性最終會(huì)出現(xiàn)在vm上,直接讀取使用即可
(2)如果計(jì)算屬性要被修改,那必須寫(xiě)set函數(shù)去響應(yīng)修改,且set中要引起計(jì)算時(shí)依賴(lài)的數(shù)據(jù)發(fā)生改變
<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 在啟動(dòng)時(shí)生成生產(chǎn)提示。 const vm = new Vue({ el:'#root', data:{ firstName:'張', lastName:'三' }, computed:{ fullName:{ //get有什么作用?當(dāng)有人讀取fullName時(shí),get就會(huì)被調(diào)用,且返回值就作為fullName的值 //get什么時(shí)候調(diào)用?1.初次讀取fullName時(shí)。2.所依賴(lài)的數(shù)據(jù)發(fā)生變化時(shí)。 get(){ console.log('get被調(diào)用了') // console.log(this) //此處的this是vm return this.firstName + '-' + this.lastName }, //set什么時(shí)候調(diào)用? 當(dāng)fullName被修改時(shí)。 set(value){ console.log('set',value) const arr = value.split('-') this.firstName = arr[0] this.lastName = arr[1] } } // 簡(jiǎn)寫(xiě),只有g(shù)et方法時(shí)可簡(jiǎn)寫(xiě),一般計(jì)算屬性也不需要set方法 fullName(){ return this.firstName + "-" + this.lastName } } }) </script>
監(jiān)視屬性
1.當(dāng)被監(jiān)視的屬性變化時(shí),回調(diào)函數(shù)自動(dòng)調(diào)用,進(jìn)行相關(guān)操作
2.監(jiān)視的屬性必須存在,才能進(jìn)行監(jiān)視
3.監(jiān)視的兩張方法:
(1)new Vue時(shí)傳入watch的配置
(2)通過(guò)vm.$watch監(jiān)視
<div id="root"> <h2>今天天氣很{{info}}</h2> <button @click="changeWeather">切換天氣</button> </div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在啟動(dòng)時(shí)生成生產(chǎn)提示。 const vm = new Vue({ el:'#root', data:{ isHot:true, }, computed:{ info(){ return this.isHot ? '炎熱' : '涼爽' } }, methods: { changeWeather(){ this.isHot = !this.isHot } }, /* watch:{ isHot:{ immediate:true, //初始化時(shí)讓handler調(diào)用一下 //handler什么時(shí)候調(diào)用?當(dāng)isHot發(fā)生改變時(shí)。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } } } */ }) vm.$watch('isHot',{ immediate:true, //初始化時(shí)讓handler調(diào)用一下 //handler什么時(shí)候調(diào)用?當(dāng)isHot發(fā)生改變時(shí)。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } }) </script>
4.深度監(jiān)視
(1)vue中watch默認(rèn)不監(jiān)測(cè)對(duì)象內(nèi)部值的改變(一層)
(2)配置deep:true可以監(jiān)測(cè)對(duì)象內(nèi)部值改變(多層)
(3)Vue自身可以監(jiān)測(cè)對(duì)象內(nèi)部值的改變,但Vue提供的watch默認(rèn)不可以
(4)使用watch時(shí)根據(jù)數(shù)據(jù)的具體結(jié)構(gòu),決定是否采用深度監(jiān)視
<div id="root"> <h2>今天天氣很{{info}}</h2> <button @click="changeWeather">切換天氣</button> <hr/> <h3>a的值是:{{numbers.a}}</h3> <button @click="numbers.a++">點(diǎn)我讓a+1</button> <h3>b的值是:{{numbers.b}}</h3> <button @click="numbers.b++">點(diǎn)我讓b+1</button> <button @click="numbers = {a:666,b:888}">徹底替換掉numbers</button> {{numbers.c.d.e}} </div> <script type="text/javascript"> const vm = new Vue({ el:'#root', data:{ isHot:true, numbers:{ a:1, b:1, c:{ d:{ e:100 } } } }, computed:{ info(){ return this.isHot ? '炎熱' : '涼爽' } }, methods: { changeWeather(){ this.isHot = !this.isHot } }, watch:{ /* isHot:{ // immediate:true, //初始化時(shí)讓handler調(diào)用一下 //handler什么時(shí)候調(diào)用?當(dāng)isHot發(fā)生改變時(shí)。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } },*/
// 簡(jiǎn)寫(xiě)
isHot(newValue,oldValue) {
console.log('isHot被修改了',newValue,oldValue,this)
}
//監(jiān)視多級(jí)結(jié)構(gòu)中某個(gè)屬性的變化 /* 'numbers.a':{ handler(){ console.log('a被改變了') } } */ //監(jiān)視多級(jí)結(jié)構(gòu)中所有屬性的變化 numbers:{ deep:true, handler(){ console.log('numbers改變了') } } } })
</script>
computed和watch之間的區(qū)別:
1.computed能完成的功能,watch都可以完成
2.watch能完成的功能,computed不一定能完成。例如:watch可以進(jìn)行異步操作
兩個(gè)重要的小原則
1.被Vue管理的函數(shù),最好寫(xiě)成普通函數(shù),這樣this指向就是vm或組件實(shí)例對(duì)象
2.不被vue所管理的函數(shù)(定時(shí)器的回調(diào)函數(shù)、ajax的回調(diào)函數(shù)等,Promise的回調(diào)函數(shù))最好寫(xiě)成箭頭函數(shù)
<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"> const vm = new Vue({ el:'#root', data:{ firstName:'張', lastName:'三', fullName:'張-三' }, watch:{ firstName(val){ setTimeout(()=>{ console.log(this) this.fullName = val + '-' + this.lastName },1000); }, lastName(val){ this.fullName = this.firstName + '-' + val } } }) </script>

浙公網(wǎng)安備 33010602011771號(hào)