本篇内容主要讲解“Vue3中watch如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue3中watch如何使用”吧!
watch(WatcherSource, Callback, [WatchOptions])
type WatcherSource<T> = Ref<T> | (() => T)
interface WatchOptions extends WatchEffectOptions {
deep?: boolean // 默认:false
immediate?: boolean // 默认:false
}
参数说明:
WatcherSource: 用于指定要侦听的响应式变量。WatcherSource可传入ref响应式数据,reactive响应式对象要写成函数的形式。
Callback: 执行的回调函数,可依次接收当前值newValue,先前值oldValue作为入参。
WatchOptions:支持 deep、immediate。当需要对响应式对象进行深度监听时,设置deep: true;默认情况下watch是惰性的,当我们设置immediate: true时,watch会在初始化时立即执行回调函数。
除此之外,vue3的watch还支持侦听多个响应式数据,也能手动停止watch监听。
<template>
<div class="watch-test">
<div>name:{{name}}</div>
<div>age:{{age}}</div>
</div>
<div>
<button @click="changeName">改变名字</button>
<button @click="changeAge">改变年龄</button>
</div>
</template>
<script>
import {ref, watch} from 'vue'
export default {
name: 'Home',
setup() {
const name = ref('小松菜奈')
const age = ref(25)
const watchFunc = watch([name, age], ([name, age], [prevName, prevAge]) => {
console.log('newName', name, 'oldName', prevName)
console.log('newAge', age, 'oldAge', prevAge)
if (age > 26) {
watchFunc() // 停止监听
}
},{immediate:true})
const changeName = () => {
name.value = '有村架纯'
}
const changeAge = () => {
age.value += 2
}
return {
name,
age,
changeName,
changeAge
}
}
}
</script>
现象:当改变名字和年龄时,watch都监听到了数据的变化。当age大于26时,我们停止了监听,此时再改变年龄,由于watch的停止,导致watch的回调函数失效。
结论:我们可以通过watch侦听多个值的变化,也可以利用给watch函数取名字,然后通过执行名字()函数来停止侦听。
<template>
<div class="watch-test">
<div>ref定义数组:{{arrayRef}}</div>
<div>reactive定义数组:{{arrayReactive}}</div>
</div>
<div>
<button @click="changeArrayRef">改变ref定义数组第一项</button>
<button @click="changeArrayReactive">改变reactive定义数组第一项</button>
</div>
</template>
<script>
import {ref, reactive, watch} from 'vue'
export default {
name: 'WatchTest',
setup() {
const arrayRef = ref([1, 2, 3, 4])
const arrayReactive = reactive([1, 2, 3, 4])
//ref not deep
const arrayRefWatch = watch(arrayRef, (newValue, oldValue) => {
console.log('newArrayRefWatch', newValue, 'oldArrayRefWatch', oldValue)
})
//ref deep
const arrayRefDeepWatch = watch(arrayRef, (newValue, oldValue) => {
console.log('newArrayRefDeepWatch', newValue, 'oldArrayRefDeepWatch', oldValue)
}, {deep: true})
//reactive,源不是函数
const arrayReactiveWatch = watch(arrayReactive, (newValue, oldValue) => {
console.log('newArrayReactiveWatch', newValue, 'oldArrayReactiveWatch', oldValue)
})
// 数组监听的最佳实践- reactive且源采用函数式返回,返回拷贝后的数据
const arrayReactiveFuncWatch = watch(() => [...arrayReactive], (newValue, oldValue) => {
console.log('newArrayReactiveFuncWatch', newValue, 'oldArrayReactiveFuncWatch', oldValue)
})
const changeArrayRef = () => {
arrayRef.value[0] = 6
}
const changeArrayReactive = () => {
arrayReactive[0] = 6
}
return {
arrayRef,
arrayReactive,
changeArrayRef,
changeArrayReactive
}
}
}
</script>
现象:当将数组定义为响应式数据ref时,如果不加上deep:true,watch是监听不到值的变化的;而加上deep:true,watch可以检测到数据的变化,但老值和新值一样,即不能获取老值。当数组定义为响应式对象时,不作任何处理,watch可以检测到数据的变化,但老值和新值一样;如果把watch的数据源写成函数的形式并通过扩展运算符克隆一份数组返回,就可以在监听的同时获得新值和老值。
结论:定义数组时,最好把数据定义成响应式对象reactive,这样watch监听时,只需要把数据源写成函数的形式并通过扩展运算符克隆一份数组返回,即可在监听的同时获得新值和老值。
<template>
<div class="watch-test">
<div>user:{</div>
<div>name:{{objReactive.user.name}}</div>
<div>age:{{objReactive.user.age}}</div>
<div>}</div>
<div>brand:{{objReactive.brand}}</div>
<div>
<button @click="changeAge">改变年龄</button>
</div>
</div>
</template>
<script>
import {ref, reactive, watch} from 'vue'
import _ from 'lodash';
export default {
name: 'WatchTest',
setup() {
const objReactive = reactive({user: {name: '小松菜奈', age: '20'}, brand: 'Channel'})
//reactive 源是函数
const objReactiveWatch = watch(() => objReactive, (newValue, oldValue) => {
console.log('objReactiveWatch')
console.log('new:',JSON.stringify(newValue))
console.log('old:',JSON.stringify(oldValue))
})
//reactive,源是函数,deep:true
const objReactiveDeepWatch = watch(() => objReactive, (newValue, oldValue) => {
console.log('objReactiveDeepWatch')
console.log('new:',JSON.stringify(newValue))
console.log('old:',JSON.stringify(oldValue))
}, {deep: true})
// 对象深度监听的最佳实践- reactive且源采用函数式返回,返回深拷贝后的数据
const objReactiveCloneDeepWatch = watch(() => _.cloneDeep(objReactive), (newValue, oldValue) => {
console.log('objReactiveCloneDeepWatch')
console.log('new:',JSON.stringify(newValue))
console.log('old:',JSON.stringify(oldValue))
})
const changeAge = () => {
objReactive.user.age = 26
}
return {
objReactive,
changeAge
}
}
}
</script>
现象:当把对象定义为响应式对象reactive时,采用函数形式的返回,如果不加上deep:true,watch是监听不到值的变化的;而加上deep:true,watch可以检测到数据的变化,但老值和新值一样,即不能获取老值;若把watch的数据源写成函数的形式并通过深拷贝克隆(这里用了lodash库的深拷贝)一份对象返回,就可以在监听的同时获得新值和老值。
结论:定义对象时,最好把数据定义成响应式对象reactive,这样watch监听时,只需要把数据源写成函数的形式并通过深拷贝克隆一份对象返回,即可在监听的同时获得新值和老值。
到此,相信大家对“Vue3中watch如何使用”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4582201/blog/4378604