vue3中的watch比起vue2中的watch有了些许的变化,我们使用composition api来写,但是其底层的核心原理其实也并没有怎么改变。但在Vue3中,由于ref定义的响应式数据在使用的时候通常要.value就显得很方便,因此,大多数情况下都使用reactive来定义基本的数据类型的监听。
首先我们先定义相关的数据类型如下
<input type="text" v-model="userName.firstName">
<input type="text" v-model="userName.lastName">
<input type="text" v-model="userName.friend.name">
<div>我的全名是:{{userName.firstName + userName.lastName}},我的朋友是{{userName.friend.name}}</div>
const userName = reactive({
firstName:'张',
lastName:'三',
friend:{
name:'李四'
}
})
vue3中的watch变成了函数形式,有三个参数,第一个是监听的对象,第二个是监听的回调,由于setup不需要考虑this的指向问题,所以可以直接在watch中写箭头函数,第三个是监听的配置项,其中就deep和immediate,分别表示的是深度监听以及立即监听;如果有两个数据需要监听可以直接写成两个watch函数。
watch(userName,(newvalue, oldValue)=>{
console.log(newvalue,oldValue)
}),
那么为什么我们监听的是一个对象,当对象中的值修改时,却也能激活这个watch的监听回调呢?原因就是其实我们在声明变量的时候是reactive来生成的基础数据,但vue3的底层是通过proxy作为中间桥梁,且vue3中针对proxy是默认开启了深度监听,即使你在后面设置deep:false也不会起相关作用。那么你说我监听这个对象里面的对象就也可以这么写了?其实也可以,我们可以将所有要监听的数据放入一个大的数据对象中,然后去监听这个大的数据对象,然后也可以完成相应的功能
watch(userName,(newvalue, oldValue)=>{
console.log('我监听到了朋友呗修改')
console.log(newvalue,oldValue)
})
但是不建议这样操作,因为这样其实监听了一些不必要的值,如果我们想监听一个对象中的对象这种值变化的情况的话,我们可以在watch中的第三个参数设置深度监听,如下图所示,这样就可以完成上面一样的功能,但这样就不需要监听整个对象。因为vue3无法直接监听对象的某个属性变化,因此要写成函数返回值这种形式,然后immediate表示的是立即监听,就好像一进来就进行了监听
watch(()=>userName.friend,(newvalue,oldValue)=>{
console.log(newvalue,oldValue)
},{deep:true,immediate:true})
但watch就不想计算属性那样,如果修改一个值,就会全部都重新根据修改的值得出结论,就没有缓存机制, 但在watch中我们进行异步操作,例如根据修改后的值发送相关请求或者啥的,例如搜索时输入文字,下面就动态匹配相关的信息。但其实watch能做的事情,在computed中也能大部分完成,在开发过程中也大多采取的computed这种写法,但watch也会有关键作用
<template>
<div>
<input type="text" v-model="userName.firstName">
<input type="text" v-model="userName.lastName">
<input type="text" v-model="userName.friend.name">
<div>我的全名是:{{userName.firstName + userName.lastName}},我的朋友是{{userName.friend.name}}</div>
</div>
</template>
<script>
import {watch,reactive} from 'vue'
export default {
name: "pageView",
setup(){
const userName = reactive({
firstName:'张',
lastName:'三',
friend:{
name:'李四'
}
})
//vue3的watch监视数学也可以完成,其中Vue3中的默认开启的是深度的监听
watch(userName,(newvalue, oldValue)=>{
console.log('我监听到了朋友呗修改')
console.log(newvalue,oldValue)
})
//vue3的watch监听整个对象的时候,其实oldValue是不起作用的,起作用的就只用newvalue
//但如果是监视的是对象中的某一个属性的时候,就可以获取到newvalue和oldValue
// watch(()=>userName.firstName,(newvalue,oldValue)=>{
// console.log(newvalue,oldValue)
// })
//但如果监听的是对象中的对象,就需要手动的开启deep:true,但有些时候我们可以监听最外面这个大对象
//这样就可以不必去deep:true
// watch(()=>userName.friend,(newvalue,oldValue)=>{
// console.log(newvalue,oldValue)
// },{deep:true,immediate:true})
//但watch就不想计算属性那样,如果修改一个值,就会全部都重新根据修改的值得出结论,就没有缓存机制,
//但在watch中我们进行异步操作,例如根据修改后的值发送相关请求或者啥的,例如搜索时输入文字,
//下面就动态匹配相关的信息
return{
userName,
}
}
}
</script>
<style scoped>
</style>