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