人人設(shè)計(jì)網(wǎng)官方網(wǎng)站cilimao磁力貓?jiān)诰€搜索
什么是偵聽器
個(gè)人理解:當(dāng)有一個(gè)響應(yīng)式狀態(tài)(普通變量 or 一個(gè)響應(yīng)式對(duì)象)發(fā)生改變時(shí),我們希望監(jiān)聽到這個(gè)改變,并且能夠進(jìn)行一些邏輯處理。那么偵聽器就是來(lái)幫助我們實(shí)現(xiàn)這個(gè)功能的。
偵聽器 其實(shí)就是兩個(gè)函數(shù),watch() 或者是 watchEffect() 。
watch() 的特點(diǎn): 被偵聽的數(shù)據(jù)源非常明確,邏輯代碼與被偵聽的數(shù)據(jù)源相互獨(dú)立,可維護(hù)性較好;
watchEffect() 的特點(diǎn):出現(xiàn)在這里邊的響應(yīng)式狀態(tài)就會(huì)被監(jiān)聽,(就是被監(jiān)聽的數(shù)據(jù)源 和 邏輯代碼 寫在一起了);watchEffect() 的監(jiān)聽是立即執(zhí)行的,不是非得等到值發(fā)生改變時(shí)才開始執(zhí)行。下面通過(guò)案例來(lái)體會(huì)一下它們的用法。
watch 偵聽器
語(yǔ)法格式:
watch(被監(jiān)聽的響應(yīng)式狀態(tài),(新值,舊值)=>{ 邏輯代碼 },{可選的配置對(duì)象})
一共有 三個(gè)參數(shù):
參數(shù)1 : 指定被監(jiān)聽的狀態(tài),可以是一個(gè)變量或?qū)ο?br /> 參數(shù)2 :監(jiān)聽到之后的響應(yīng)回調(diào)函數(shù),
參數(shù)3 :其他的屬性配置,可選的,不是很常用
【注意】:
? ?watch第一個(gè)參數(shù)可以同時(shí)監(jiān)聽多個(gè)狀態(tài),寫成數(shù)組的形式,但是筆者不建議這樣使用,如果想監(jiān)聽多個(gè)狀態(tài),可以分開一個(gè)一個(gè)的寫嘛。
watch 監(jiān)聽一個(gè) ref 的普通響應(yīng)式狀態(tài)
這是最基本的使用,直接上代碼:
一個(gè)文本輸入框,
一個(gè)普通的響應(yīng)式變量,
當(dāng)文本輸入框中的內(nèi)容發(fā)生改變時(shí),在偵聽器的邏輯中修改 普通變量的值。
<template><!-- 監(jiān)聽器的使用 --><div><!-- 普通的響應(yīng)式狀態(tài) -->textValue : <input type="text" v-model="textValue"><br>otherValue1 : {{ orhterValue1 }} <br></div></template><script setup lang="ts">import { ref,watch } from 'vue'// 聲明一個(gè) 文本輸入框的值const textValue = ref('這是文本輸入框')// 聲明一個(gè) 變量,當(dāng) textValue 發(fā)生變化時(shí),這個(gè)變量也發(fā)生變化const orhterValue1 = ref('')// 監(jiān)聽 textValue 這個(gè)變量的狀態(tài)變化watch(textValue,(newValue:string,oldValue:string)=>{console.log(`oldValue is ${oldValue}`)console.log(`newValue is ${newValue}`)console.log(`textValue is ${textValue.value}`)// 當(dāng)textValue 的值發(fā)生改變時(shí),我們修改 otherValue1 的值orhterValue1.value = '改變了'+new Date().getTime()})</script><style scoped>
</style>
運(yùn)行效果:
初始狀態(tài) | 文本框改變之后 |
---|---|
![]() | ![]() |
watch 監(jiān)聽一個(gè)reactive的響應(yīng)式對(duì)象
當(dāng)想監(jiān)聽一個(gè)對(duì)象是否發(fā)生改變時(shí),需要使用
reactive
創(chuàng)建響應(yīng)式對(duì)象;
而且,這個(gè)監(jiān)聽是深度監(jiān)聽,即,無(wú)論這個(gè)對(duì)象的屬性有多少層,都能夠被監(jiān)聽到;
而且,監(jiān)聽的回調(diào)函數(shù)的兩個(gè)參數(shù)都是一樣的,全都是新值對(duì)象,因?yàn)檫@就是一個(gè)對(duì)象!(這一條可能比較晦澀難懂,記住就行了)
案例 :
有一個(gè)響應(yīng)式的對(duì)象,
有一個(gè)按鈕,
點(diǎn)擊按鈕,改變對(duì)象的某個(gè)屬性,觸發(fā)偵聽器的邏輯
<template><!-- 監(jiān)聽器的使用 --><div><!-- 監(jiān)聽一個(gè)對(duì)象 -->stu : {{ stu }}<br><button @click="changeStu">點(diǎn)擊修改對(duì)象的屬性</button></div></template><script setup lang="ts">import { reactive,watch } from 'vue'// 聲明一個(gè)響應(yīng)式的對(duì)象const stu = reactive({id:100,name:'小紅',classInfo:{classId:'001',className:'快樂(lè)足球一班'}})// 修改對(duì)象的屬性的方法const changeStu = ()=>{stu.classInfo.className = '拒絕踢足球二班'}// 監(jiān)聽對(duì)象發(fā)生了變化 : 需要使用 reactive// 且此處的 newValue 和 oldValue 是一樣的,因?yàn)樗且粋€(gè)對(duì)象,都是更新后的值watch(stu,(newValue,oldValue)=>{console.log(`oldValue is `,oldValue)console.log(`newValue is `,newValue)console.log(`stu is `,newValue)})</script><style scoped>
</style>
運(yùn)行效果:
watch 監(jiān)聽一個(gè)對(duì)象的某個(gè)屬性
通過(guò)
getter 方法
的形式,將對(duì)象的屬性作為被偵聽的對(duì)象。
getter方法
: 其實(shí)就是寫一個(gè)簡(jiǎn)單的函數(shù),返回被偵聽的對(duì)象。
這種監(jiān)聽,無(wú)論是ref
還是reactive
聲明的響應(yīng)式對(duì)象,都是可以的。
案例 :
有一個(gè)響應(yīng)式的對(duì)象,
有一個(gè)按鈕,
點(diǎn)擊按鈕,改變對(duì)象的某個(gè)屬性,觸發(fā)偵聽器的邏輯
<template><!-- 監(jiān)聽器的使用 --><div><!-- 監(jiān)聽一個(gè)對(duì)象的其中的某個(gè)屬性 -->stu : {{ stu }}<br><button @click="changeStu">點(diǎn)擊修改對(duì)象的屬性</button></div></template><script setup lang="ts">import { reactive,watch } from 'vue'// 聲明一個(gè)響應(yīng)式的對(duì)象const stu = reactive({id:100,name:'小紅',classInfo:{classId:'001',className:'快樂(lè)足球一班'}})// 修改對(duì)象的屬性的方法const changeStu = ()=>{stu.classInfo.className = '拒絕踢足球二班'}// 通過(guò)getter 函數(shù)的方式監(jiān)聽對(duì)象某個(gè)屬性的值watch(()=> stu.classInfo.className,(newValue,oldValue)=>{console.log(`oldValue is `,oldValue)console.log(`newValue is `,newValue)console.log(`stu is `,newValue)})</script><style scoped></style>
運(yùn)行效果:
watchEffect偵聽器
特點(diǎn) :
只要是出現(xiàn)在 watchEffect 中的響應(yīng)式的狀態(tài),就會(huì)被納入監(jiān)聽,
當(dāng)響應(yīng)式狀態(tài)發(fā)生改變時(shí),會(huì)自動(dòng)觸發(fā)偵聽器的邏輯。
它可以比較方便的監(jiān)聽多個(gè)狀態(tài)值,但是,只要有一個(gè)值觸發(fā)了,就會(huì)把整個(gè)的偵聽邏輯執(zhí)行一遍!
案例 :
一個(gè)文本輸入框,可以監(jiān)聽文本輸入框的值;
一個(gè)按鈕,點(diǎn)擊修改 對(duì)象的一個(gè)屬性,該屬性被偵聽器監(jiān)聽;
<template><!-- 監(jiān)聽器的使用 --><div><!-- 普通的響應(yīng)式狀態(tài) -->textValue : <input type="text" v-model="textValue"><br><hr><!-- 監(jiān)聽一個(gè)對(duì)象 -->stu : {{ stu }}<br><button @click="changeStu">點(diǎn)擊修改對(duì)象的屬性</button></div></template><script setup lang="ts">import { ref,reactive,watchEffect} from 'vue'// 聲明一個(gè) 文本輸入框的值const textValue = ref('這是文本輸入框')// 聲明一個(gè)響應(yīng)式的對(duì)象const stu = reactive({id:100,name:'小紅',classInfo:{classId:'001',className:'快樂(lè)足球一班'}})// 修改對(duì)象的屬性的方法const changeStu = ()=>{stu.classInfo.className = '拒絕踢足球二班'}// 通過(guò) watchEffect 進(jìn)行監(jiān)聽watchEffect(()=>{// 監(jiān)聽普通的屬性if(textValue.value.length > 7){console.log('檢測(cè)到了 textValue 屬性的修改')console.log('textValue : ',textValue.value)console.log('---------------')}// 監(jiān)聽對(duì)象的屬性if(stu.classInfo.className.length > 6){console.log('檢測(cè)到了className屬性的修改')console.log('className : ',stu.classInfo.className)console.log('---------------')}})</script><style scoped>
</style>
運(yùn)行效果: