詳解Vue3?中的計(jì)算屬性及偵聽(tīng)器
計(jì)算屬性
我們知道,在模板中可以直接通過(guò)插值語(yǔ)法顯示一些data中的數(shù)據(jù),但是在某些情況,我們可能需要對(duì)數(shù)據(jù)進(jìn)行一些轉(zhuǎn)化后再顯示,或者需要將多個(gè)數(shù)據(jù)結(jié)合起來(lái)進(jìn)行顯示
在模板中使用表達(dá)式,可以非常方便的實(shí)現(xiàn),但是設(shè)計(jì)它們的初衷是用于簡(jiǎn)單的運(yùn)算,在模板中放入太多的邏輯會(huì)讓模板過(guò)重和難以維護(hù),并且如果多個(gè)地方都使用到,那么會(huì)有大量重復(fù)的代碼
所以我們希望將業(yè)務(wù)邏輯和UI界面進(jìn)行分離,其中一種方式就是將邏輯抽取到一個(gè)method中,但這種做法有以下弊端
- 所有的data使用過(guò)程都會(huì)變成了一個(gè)方法的調(diào)用
- 多次獲取數(shù)據(jù),需要多次調(diào)用方法,執(zhí)行對(duì)應(yīng)的邏輯,沒(méi)有緩存
事實(shí)上,對(duì)于任何包含響應(yīng)式數(shù)據(jù)的復(fù)雜邏輯,你都應(yīng)該使用計(jì)算屬性
<div id="app">
<!-- 計(jì)算屬性的使用和普通狀態(tài)的使用方式是一致的 -->
<h2>{{ fullname }}</h2>
</div>
<script>
Vue.createApp({
data() {
return {
firstname: 'Klaus',
lastname: 'Wang'
}
},
computed: {
fullname() {
return this.firstname + ' ' + this.lastname
}
}
}).mount('#app')緩存
計(jì)算屬性會(huì)基于它們的依賴(lài)關(guān)系進(jìn)行緩存,在數(shù)據(jù)不發(fā)生變化時(shí),計(jì)算屬性是不需要重新計(jì)算的
但是如果依賴(lài)的數(shù)據(jù)發(fā)生變化,在使用時(shí),計(jì)算屬性依然會(huì)重新進(jìn)行計(jì)算
并且界面會(huì)使用最新的計(jì)算屬性的值進(jìn)行重新渲染
getter 和 setter
計(jì)算屬性在大多數(shù)情況下,只需要一個(gè)getter方法即可,所以我們會(huì)將計(jì)算屬性直接寫(xiě)成一個(gè)函數(shù)
<div id="app">
<!-- 計(jì)算屬性的使用和普通狀態(tài)的使用方式是一致的 -->
<h2>{{ fullname }}</h2>
<button @click="change">change</button>
</div>
<script>
Vue.createApp({
data() {
return {
firstname: 'Klaus',
lastname: 'Wang'
}
},
methods: {
change() {
this.fullname = 'Alex Li'
}
},
computed: {
// 計(jì)算屬性的完整寫(xiě)法
fullname: {
get() {
return this.firstname + ' ' + this.lastname
},
set(v) {
this.firstname = v.split(' ')[0]
this.lastname = v.split(' ')[1]
}
}
}
}).mount('#app')
</script>偵聽(tīng)器
在data返回的對(duì)象中定義了數(shù)據(jù),這個(gè)數(shù)據(jù)通過(guò)插值語(yǔ)法等方式綁定到template中,當(dāng)數(shù)據(jù)變化時(shí),template會(huì)自動(dòng)進(jìn)行更新來(lái)顯示最新的數(shù)據(jù)
但是在某些情況下,我們希望在代碼邏輯中監(jiān)聽(tīng)某個(gè)數(shù)據(jù)的變化,這個(gè)時(shí)候就需要用偵聽(tīng)器watch來(lái)完成了
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
// 可以使用watch監(jiān)聽(tīng)響應(yīng)式數(shù)據(jù)的改變
// 對(duì)應(yīng)有兩個(gè)參數(shù)
// 參數(shù)一 --- 新值
// 參數(shù)二 --- 舊值
info(newV, oldV) {
// 如果監(jiān)聽(tīng)的值是對(duì)象,獲取到的新值和舊值是對(duì)應(yīng)對(duì)象的代理對(duì)象
console.log(newV, oldV)
// 代理對(duì)象 轉(zhuǎn) 原生對(duì)象
// 1. 使用淺拷貝獲取一個(gè)新的對(duì)象,獲取的新的對(duì)象為原生對(duì)象
console.log({...newV})
// 2. 使用Vue.toRaw方法獲取原生對(duì)象
console.log(Vue.toRaw(newV))
}
},
methods: {
change() {
this.info = {
name: 'Steven'
}
}
}
}).mount('#app')配置選項(xiàng)
| 屬性 | 說(shuō)明 |
|---|---|
| deep | 是否開(kāi)啟深度監(jiān)聽(tīng) 值為boolean 未開(kāi)啟的時(shí)候,如果監(jiān)聽(tīng)的是對(duì)象,那么只有對(duì)象的引用發(fā)生改變的時(shí)候,才會(huì)觸發(fā)watch回調(diào) 開(kāi)始后,如果監(jiān)聽(tīng)的是對(duì)象,那么只要對(duì)象中的任意一個(gè)屬性發(fā)生了改變,就會(huì)觸發(fā)watch回調(diào) |
| immediate | 是否立即開(kāi)始監(jiān)聽(tīng) 默認(rèn)情況下,初次渲染是不會(huì)觸發(fā)watch監(jiān)聽(tīng),只有當(dāng)值發(fā)生改變后,才會(huì)觸發(fā)watch監(jiān)聽(tīng) 將immediate設(shè)置為true后,初次渲染也會(huì)觸發(fā)watch監(jiān)聽(tīng),此時(shí)oldValue的值為undefined |
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
info: {
// 開(kāi)啟了深度監(jiān)聽(tīng)后,當(dāng)info的屬性發(fā)生改變的時(shí)候,就會(huì)觸發(fā)對(duì)應(yīng)的watch回調(diào)
// 注意: 和直接修改info引用不同的是,如果直接修改的是對(duì)象的屬性
// 那么此時(shí)newV和oldV是同一個(gè)對(duì)象的引用, 此時(shí)也就獲取不到對(duì)應(yīng)的舊值
handler(newV, oldV) {
console.log(newV, oldV)
console.log(newV === oldV) // => true
},
deep: true,
immediate: true
}
},
methods: {
change() {
this.info.name = 'Steven'
}
}
}).mount('#app')其它寫(xiě)法
直接監(jiān)聽(tīng)對(duì)象屬性
watch: {
'info.name'(newV, oldV){
console.log(newV, oldV)
}
}字符串寫(xiě)法
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
// watch的值如果是一個(gè)字符串的時(shí)候
// 會(huì)自動(dòng)以該字符串作為函數(shù)名去methods中查找對(duì)應(yīng)的方法
'info.name': 'watchHandler'
},
methods: {
change() {
this.info.name = 'Steven'
},
watchHandler(newV, oldV){
console.log(newV, oldV)
}
}
}).mount('#app')數(shù)組寫(xiě)法
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
'info.name': [
'watchHandler',
function handle() {
console.log('handler2')
},
{
handler() {
console.log('handler3')
}
}
]
},
methods: {
change() {
this.info.name = 'Steven'
},
watchHandler(){
console.log('handler1')
}
}
}).mount('#app')$watch
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
created() {
/*
$watch 參數(shù)列表
參數(shù)一 --- 偵聽(tīng)源
參數(shù)二 --- 偵聽(tīng)回調(diào)
參數(shù)三 --- 配置對(duì)象
*/
this.$watch('info.name', (newV, oldV) => console.log(newV, oldV), {
immediate: true
})
},
methods: {
change() {
this.info.name = 'Steven'
}
}
}).mount('#app')到此這篇關(guān)于詳解Vue3 中的計(jì)算屬性及偵聽(tīng)器的文章就介紹到這了,更多相關(guān)Vue偵聽(tīng)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+ElementUi+iframe實(shí)現(xiàn)輪播不同的網(wǎng)站
需要實(shí)現(xiàn)一個(gè)輪播圖,輪播內(nèi)容是不同的網(wǎng)站,并實(shí)現(xiàn)鼠標(biāo)滑動(dòng)時(shí)停止輪播,當(dāng)鼠標(biāo)10秒內(nèi)不動(dòng)時(shí)繼續(xù)輪播,所以本文給大家介紹了用vue+ElementUi+iframe實(shí)現(xiàn)輪播不同的網(wǎng)站,需要的朋友可以參考下2024-02-02
基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件
本文給大家介紹基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件,此篇教程需要大家具備一定的css和vue基礎(chǔ)知識(shí),本文分步驟給大家介紹的非常詳細(xì),需要的朋友參考下吧2017-11-11
解決Vue中 父子傳值 數(shù)據(jù)丟失問(wèn)題
這篇文章主要介紹了解決Vue中 父子傳值 數(shù)據(jù)丟失問(wèn)題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
Vue彈窗Dialog最佳使用方案實(shí)戰(zhàn)
這篇文章主要為大家介紹了極度舒適的Vue彈窗Dialog最佳使用方案實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
vue2+el-menu實(shí)現(xiàn)路由跳轉(zhuǎn)及當(dāng)前項(xiàng)的設(shè)置方法實(shí)例
這篇文章主要介紹了vue2+el-menu實(shí)現(xiàn)路由跳轉(zhuǎn)及當(dāng)前項(xiàng)的設(shè)置,方法實(shí)例代碼詳解,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11
vue中使用echarts實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)綁定以及獲取后端接口數(shù)據(jù)
總結(jié)一下自己最近項(xiàng)目中用echarts動(dòng)態(tài)獲取接口數(shù)據(jù)并畫(huà)圖的方法,下面這篇文章主要給大家介紹了關(guān)于vue中使用echarts實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)綁定以及獲取后端接口數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2022-07-07

