一文搞懂Vue中computed和watch的區(qū)別
一、computed介紹
computed 用來(lái)監(jiān)控自己定義的變量,該變量在 data 內(nèi)沒(méi)有聲明,直接在 computed 里面定義,頁(yè)面上可直接使用。
//基礎(chǔ)使用 {{msg}} <input v-model="name" /> //計(jì)算屬性 computed:{ msg:function(){ return this.name } }
在輸入框中,改變 name 值得時(shí)候,msg 也會(huì)跟著改變。這是因?yàn)?computed 監(jiān)聽(tīng)自己的屬性 msg,發(fā)現(xiàn) name 一旦變動(dòng),msg 立馬會(huì)更新。
注意:msg 不可在 data 中定義,否則會(huì)報(bào)錯(cuò)。
1.1、get 和 set 用法
<input v-model="full" ><br> <input v-model="first" > <br> <input v-model="second" > data(){ return{ first:'美女', second:'姐姐' } }, computed:{ full:{ get(){ //回調(diào)函數(shù) 當(dāng)需要讀取當(dāng)前屬性值是執(zhí)行,根據(jù)相關(guān)數(shù)據(jù)計(jì)算并返回當(dāng)前屬性的值 return this.first + ' ' + this.second }, set(val){ //監(jiān)視當(dāng)前屬性值的變化,當(dāng)屬性值發(fā)生變化時(shí)執(zhí)行,更新相關(guān)的屬性數(shù)據(jù) let names = val.split(' ') this.first = names[0] this.second = names[1] } } }
get 方法:first 和 second 改變時(shí),會(huì)調(diào)用 get 方法,更新 full 的值。
set 方法:修改 full 的值時(shí),會(huì)調(diào)用 set 方法,val 是 full 的最新值。
1.2、計(jì)算屬性緩存
我們通過(guò)方法,拼接數(shù)據(jù),也可以實(shí)現(xiàn)該效果,代碼如下。
<div> {{ full() }} </div> data(){ return{ first:'美女', second:'姐姐' } }, methods:{ full(){ return this.first + ' ' + this.second } },
一個(gè)頁(yè)面內(nèi),數(shù)據(jù)有可能多次使用,我們把 computed 和 method 兩個(gè)方法放一起實(shí)現(xiàn),并把這個(gè)數(shù)據(jù)在頁(yè)面內(nèi)多次引用,試看以下效果。
<div> computed計(jì)算值: {{full}} {{full}} {{full}} {{full}} </div> <div> methods計(jì)算值: {{fullt}} {{fullt}} {{fullt}} {{fullt}} </div> data(){ return{ first:'美女', second:'姐姐' } }, computed:{ full:function(){ console.log('computed') return this.first + ' ' + this.second } }, methods:{ fullt(){ console.log('方法') return this.first + ' ' + this.second } }
運(yùn)行結(jié)果為:
根據(jù)結(jié)果,我們不難發(fā)現(xiàn),根據(jù)方法獲取到的數(shù)據(jù),使用幾次就需要重新計(jì)算幾次,但計(jì)算屬性不是,而是基于它們的響應(yīng)式依賴(lài)進(jìn)行緩存的,之后依賴(lài)屬性值發(fā)生改變的時(shí)候,才會(huì)重新計(jì)算。由于它計(jì)算次數(shù)少,所以性能更高些。
二、watch介紹
watch 是監(jiān)測(cè) Vue 實(shí)例上的數(shù)據(jù)變動(dòng),通俗地講,就是檢測(cè) data 內(nèi)聲明的數(shù)據(jù)。不僅可以監(jiān)測(cè)簡(jiǎn)單數(shù)據(jù),還可以監(jiān)測(cè)對(duì)象或?qū)ο髮傩浴?/p>
Demo1:監(jiān)測(cè)簡(jiǎn)單數(shù)據(jù)
<input v-model="first" > <br> data(){ return{ first:'美女', } }, watch:{ first( newVal , oldVal ){ console.log('newVal',newVal) // first 的最新值 console.log('oldVal',oldVal) // first上一個(gè)值 } }, // 修改 first的值的時(shí)候,立馬會(huì)打印最新值
Demo2:監(jiān)測(cè)對(duì)象
監(jiān)聽(tīng)對(duì)象的時(shí)候,需要使用深度監(jiān)聽(tīng)。
<input v-model="per.name"> data(){ return{ per:{ name:'倩倩', age:'18' } } }, watch:{ per:{ handler(oldVal,newVal){ console.log('newVal',newVal) console.log('oldVal',oldVal) }, deep:true, } },
修改 per.name 的時(shí)候,發(fā)現(xiàn) newVal 和 oldVal 的值是一樣的,是因?yàn)樗麄兇鎯?chǔ)的指針指向的是同一個(gè)地方,所以深度監(jiān)聽(tīng)雖然可以監(jiān)聽(tīng)到對(duì)象的變化,但是無(wú)法監(jiān)聽(tīng)到具體的是哪個(gè)屬性發(fā)生變化了。
Demo3:監(jiān)聽(tīng)對(duì)象的單個(gè)屬性
// 方法1:直接引用對(duì)象的屬性 <input v-model="per.name"> data(){ return{ per:{ name:'倩倩', age:'18' } } }, watch:{ 'per.name':function(newVal,oldVal){ console.log('newVal->',newVal) console.log('oldVal->',oldVal) } },
也可以借助 computed 作為中間轉(zhuǎn)換,如下:
// 方法2:借助computed <input v-model="per.name"> data(){ return{ per:{ name:'倩倩', age:'18' } } }, watch:{ perName(){ console.log('name改變了') } }, computed:{ perName:function(){ return this.per.name } },
Demo4:監(jiān)聽(tīng) props 組件傳過(guò)來(lái)的值
props:{ mm:String }, //不使用 immediate watch:{ mm(newV,oldV){ console.log('newV',newV) console.log('oldV',oldV) } } //使用 immediate watch:{ mm:{ immediate:true, handler(newV,oldV){ console.log('newV',newV) console.log('oldV',oldV) } }
不使用 immediate 時(shí),第一次加載頁(yè)面時(shí),watch 監(jiān)聽(tīng)的 mm 中的打印并沒(méi)有執(zhí)行。
使用 immediate 時(shí),第一次加載時(shí)也會(huì)打印結(jié)果:newV 11 oldV undefined。
immediate 主要作用就是組件加載時(shí),會(huì)立即觸發(fā)回調(diào)函數(shù)。
三、兩者區(qū)別
3.1、對(duì)于 computed
- computed 監(jiān)控的數(shù)據(jù)在 data 中沒(méi)有聲明
- computed 不支持異步,當(dāng) computed 中有異步操作時(shí),無(wú)法監(jiān)聽(tīng)數(shù)據(jù)的變化
- computed 具有緩存,頁(yè)面重新渲染,值不變時(shí),會(huì)直接返回之前的計(jì)算結(jié)果,不會(huì)重新計(jì)算
- 如果一個(gè)屬性是由其他屬性計(jì)算而來(lái)的,這個(gè)屬性依賴(lài)其他屬性,一般使用 computed
- computed 計(jì)算屬性值是函數(shù)時(shí),默認(rèn)使用get方法。如果屬性值是屬性值時(shí),屬性有一個(gè)get和set方法,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)會(huì)調(diào)用set方法。
computed:{ //屬性值為函數(shù) perName:function(){ return this.per.name }, //屬性值為屬性值 full:{ get(){ }, set(val){ } } },
3.2、對(duì)于 watch
- 監(jiān)測(cè)的數(shù)據(jù)必須在 data 中聲明或 props 中數(shù)據(jù)
- 支持異步操作
- 沒(méi)有緩存,頁(yè)面重新渲染時(shí),值不改變時(shí)也會(huì)執(zhí)行
- 當(dāng)一個(gè)屬性值發(fā)生變化時(shí),就需要執(zhí)行相應(yīng)的操作
- 監(jiān)聽(tīng)數(shù)據(jù)發(fā)生變化時(shí),會(huì)觸發(fā)其他操作,函數(shù)有兩個(gè)參數(shù):
immediate :組件加載立即觸發(fā)回調(diào)函數(shù)
deep:深度監(jiān)聽(tīng),主要針對(duì)復(fù)雜數(shù)據(jù),如監(jiān)聽(tīng)對(duì)象時(shí),添加深度監(jiān)聽(tīng),任意的屬性值改變都會(huì)觸發(fā)。
注意:對(duì)象添加深度監(jiān)聽(tīng)之后,輸出的新舊值是一樣的。
computed 頁(yè)面重新渲染時(shí),不會(huì)重復(fù)計(jì)算,而 watch 會(huì)重新計(jì)算,所以 computed 性能更高些。
四、應(yīng)用場(chǎng)景
當(dāng)需要進(jìn)行數(shù)值計(jì)算,并且依賴(lài)于其它數(shù)據(jù)時(shí),應(yīng)該使用 computed ,因?yàn)榭梢岳?computed 的緩存特性,避免每次獲取值時(shí)都要重新計(jì)算。
當(dāng)需要在數(shù)據(jù)變化時(shí)執(zhí)行異步操作或開(kāi)銷(xiāo)較大的操作時(shí),應(yīng)該使用 watch,computed 不支持異步。如果需要限制執(zhí)行操作的頻率,可借助 computed 作為中間狀態(tài)。
到此這篇關(guān)于一文搞懂Vue中computed和watch的區(qū)別的文章就介紹到這了,更多相關(guān)Vue computed watch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過(guò)vue-router懶加載解決首次加載時(shí)資源過(guò)多導(dǎo)致的速度緩慢問(wèn)題
這篇文章主要介紹了vue-router懶加載解決首次加載時(shí)資源過(guò)多導(dǎo)致的速度緩慢問(wèn)題,文中單獨(dú)給大家介紹了vue router路由懶加載問(wèn)題,需要的朋友可以參考下2018-04-04Vue el使用el-checkbox-group復(fù)選框進(jìn)行單選框方式
這篇文章主要介紹了Vue el使用el-checkbox-group復(fù)選框進(jìn)行單選框方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue.js如何利用v-for循環(huán)生成動(dòng)態(tài)標(biāo)簽
這篇文章主要給大家介紹了關(guān)于Vue.js如何利用v-for循環(huán)生成動(dòng)態(tài)標(biāo)簽的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01Vue實(shí)現(xiàn)用戶沒(méi)有登陸時(shí),訪問(wèn)后自動(dòng)跳轉(zhuǎn)登錄頁(yè)面的實(shí)現(xiàn)思路
這篇文章主要介紹了Vue實(shí)現(xiàn)用戶沒(méi)有登陸時(shí),訪問(wèn)后自動(dòng)跳轉(zhuǎn)登錄頁(yè)面,定義路由的時(shí)候配置屬性,這里使用needLogin標(biāo)記訪問(wèn)頁(yè)面是否需要登錄,本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02vue-loader和webpack項(xiàng)目配置及npm錯(cuò)誤問(wèn)題的解決
這篇文章主要介紹了vue-loader和webpack項(xiàng)目配置及npm錯(cuò)誤問(wèn)題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07el-tab設(shè)置默認(rèn)激活的標(biāo)簽頁(yè)實(shí)現(xiàn)步驟
這篇文章主要給大家介紹了關(guān)于el-tab設(shè)置默認(rèn)激活的標(biāo)簽頁(yè)實(shí)現(xiàn)步驟,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09Vue.js項(xiàng)目實(shí)戰(zhàn)之多語(yǔ)種網(wǎng)站的功能實(shí)現(xiàn)(租車(chē))
這篇文章主要介紹了Vue.js項(xiàng)目實(shí)戰(zhàn)之多語(yǔ)種網(wǎng)站(租車(chē))的功能實(shí)現(xiàn) ,需要的朋友可以參考下2019-08-08詳解Vue實(shí)現(xiàn)鏈接生成二維碼并支持下載
在現(xiàn)代 Web 應(yīng)用中,快速分享鏈接是一項(xiàng)常見(jiàn)需求,二維碼作為一種簡(jiǎn)潔的分享方式,受到了廣泛歡迎,所以本文將介紹如何使用 Vue 純前端技術(shù)實(shí)現(xiàn)動(dòng)態(tài)生成鏈接二維碼的方法,需要的可以參考下2024-03-03