「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」
Vue2.0的Watch想必大家已经很熟悉了,但是Vue3.0的Watch的用法,可能大家还不是特别熟练,所以我专门整理了一篇Vue3.0中关于Watch的几种用法,让在学习Vue3的小伙伴加以熟练!更加深入解和使用Watch!相信看完对你会有所帮助!
废话不多说,我们先来看Vue2.0中的最常见的用法
Vue2.0中的最常见的Watch用法:🐱👤
//数据
let sum = ref(0)
watch: {
//简单监听
sum(newValue,oldValue){
console.log('sum的值变化了',newValue,oldValue)
}
},
我定义了一个sum数值,在HTML 我写了一个点击事件,通过watch 我们就可以去监听到sum值得变化。这里得为更新之后前得值,为更新之后得值!
这是一个最简单得监听,相信大家也都特别熟练,这里如果我们如果想在页面加载之后就进行一个即刻监听得话,我们可以给他在watch中增加两个值,也就是我们熟悉的
immediate: true, // 立即监听
如果想深度监听的话,我们则需要添加
deep: true, // 深度监听
以上就是Vue2.0中的监听用法,这里也不过多的去描述。
接下来我们来看一下
Vue3.0中Watch变化
首先,Watch在3.0中可以传递三个参数:
- 参数一
- 参数二
- 参数三
我们先来看🐱🐉
情况一:
//情况一:监视ref所定义的一个响应式数据
/* watch(sum, (newValue, oldValue) => {
console.log('sum值变化了', newValue, oldValue)
}, {immediate: true})*/
我们可以清楚的看到,三个参数我都配置上了,在配置项中,我开启了即刻监听。 我们来看一下控制台:
效果显然易见,这就是在3.0中情况一的用法。
注意:这里监听的数据源是
//数据源
let sum = ref(0)
之所以提出来数据源,是因为后面会有所不同,让我们继续往下走✨
情况二:
//数据源
let sum = ref(0)
let msg = ref('你好啊,我是多个')
//情况二:监视ref所定义的多个个响应式数据
watch([sum, msg], (newValue, oldValue) => {
console.log('sum或msg变化了', newValue, oldValue)
})
从以上二种情况来看,其实变化并不是很大,而且我们上面监听的都是用ref定义的基本数据类型。
我们来看第三种情况,也就是会出现问题的情况三(最常用的一种情况!)。
情况三 是用来监视reactive所定义的一个响应式数据
情况三就比较有意思了,因为在情况三里,存在二个的问题🤦♂️:
- 问题一: 你无法正确获取修改之前的值
- 问题二: 强制开启了深度监听(无法关闭)
情况三:
// 源数据 reactive
let person = reactive({
name: "李雷",
age: 18,
obj: {
height: "186",
obj2: {
ppp: 222
}
}
})
watch(person, (newValue, oldValue) => {
console.log('person值变化了', newValue, oldValue)
})
有兴趣的朋友可以去写一下,看看能不能关掉深度监听。
我尝试的是不能关闭!
不过,后面我会写出解决这二个问题的办法,还请您看完之后帮忙点一个小小赞~ 祝您生活愉快!涨薪!
看到这里你可能就会想了,如果我想监听某一个属性我们应该咋办哪? 情况四,来帮你解决疑问。
情况四:
let person = reactive({
name: "李雷",
age: 18,
obj: {
height: "186",
obj2: {
ppp: 222
}
}
})
//情况四:监视reactive所定义的一个响应式数据中的某一个属性
watch(()=>person.age, (newValue, oldValue) => {
console.log('person里面的age值变化了', newValue, oldValue)
})
没错,我们可以把第一个参数写成函数的形式,你想监听谁,你就把谁写成函数,函数有返回值,就是你监听的哪一个值!
情况五:
情况五也是类似的,只不过是监视的多个值
//情况五:监视reactive所定义的一个响应式数据中的多个属性
/* watch([()=>person.age,()=>person.name], (newValue, oldValue) => {
console.log('person值变化了', newValue, oldValue)
})
接下来我们来看二种特殊情况:
特殊情况一:
//对象reactive
let person = reactive({
name: "李雷",
age: 18,
obj: {
height: "186",
obj2: {
ppp: 222
}
}
})
//特殊情况 深度监视对象里面套对象的值 需要开启deep
/* watch([()=>person.obj], (newValue, oldValue) => {
console.log('person值变化了', newValue, oldValue)
},{deep:true})
//此处监听的是reactive定义对象中的某一个属性 所以得配置 deep*/
特殊情况二 (当你想去监听ref的对象时):
当你去监听ref基本类型的时候,如果你在ref写的是对象类型,则ref会找到他的大哥帮助(reactive),也就是说 你在对象数据类型里面去使用ref做监听的话,他实际上还是调用的 reactive。
所以当你想监听的时候,需要写 personRef.value或者开启深度监听 deep:true
//ref
let personRef = ref({
names: "韩梅梅",
age: 20,
obj: {
height: "195",
obj2: {
ppp: 333
}
}
})
// 一个注意点 如果在 ref的基本类型值,写了.value watch(msg.value, () => {}
// 他会监听的是值的本身,所以这样并不可行
watch(personRef.value, (newValue, oldValue) => {
console.log('person值变化了', oldValue, oldValue)
})
注意:在这里我们监测的数据源发生了变话,我们不在是监测的reactive数据源,而是ref!
如果我们在这里不写personRef.value, 我们直接去写 personRef的话,我们监测的并不是对象里面的值,而是ref在解析的过程所生产的Reflmpl{...对象...} 这里所有生产的则是value:Proxy。而在Proxy里面才会有我们真正想监测的值! 使用personRef.value的话,我们是监测到的是Reflmpl所生产的 value --> Proxy。
以上就是我们聊到的 5种情况、加2种特殊情况的用法😉
我们再来讨论一下,三个API
- watchEffect() // 监听全局属性
- shallowReactive() // 浅度监听
- shallowRef() // 只处理基本的数据类型 不进行对象的处理
watchEffect() 监听全局属性
-
watch的套路:既要指明监视属性,也要指明监视的回调。
-
watchEffect的套路是:不用指明监视的那个属性,监视的回调函数中用到哪个属性,那就监视那个属性
-
watchEffect有点像computed: (重点,面试可以聊)
- 但computed的计算出来的值(回调函数的返回值),所以必须要写返回值
- 而watchEffect更注重的过程(回调函数的函数体),所以不用写返回值
// watchEffect() 函数可以监听全局, 有个最大的特点就是 在函数里面你用到了谁
// 他就会监听谁,否则谁也不会监听,但是会认为开启立即监听。
watchEffect(() => {
const x1 = sum.value;
console.log(x1)
console.log('watchEffect执行了!')
})
shallowReactive() 浅度监听
// shallowReactive 只考虑第一层的响应式数据
/* let person = shallowReactive({
name: "xuge",
age: 18,
obj: {
aa: "文字",
j1: {
pop: 222
}
}
})*/
shallowRef() 只处理基本的数据类型 不进行对象的处理
// shallowRef 值处理基本的数据类型 不进行对象的处理
// 这里如果换成 ref 是可以进行 响应式点击的,如果是shallowRef则不可以进行处理对象
let x = shallowRef({
y: 0
})
注意: ref 会求助 reactive 所以 里面也是可以改变的所以是响应式, 但是shallowRef 不会求助任何属性 所以里面不会是响应式。
//深层次的去限制 响应式改变
// x1 = shallowReactive(person)
//浅层次的去限制 响应式改变
// x2 = readonly(x)
当然,这里还有很多细节,我并没有展开为话题进行叙述。
这里推荐几个值得你研究的问题:
- watchEffect与 watch 有什么不同?(这里做了简便的回答,具体可以去官网查看对比!) 答:
- watch可以查看旧值, watchEffect不可以
- watch只有属性改变才执行, watchEffect初始执行一次,属性改变再执行
- watch要指定属性, watchEffect不需要
- watch不可以停止监听, watchEffect可以
- watch多次触发多次执行(不能节流), watchEffect可以
- 基本类型 ref 和 shallowref 没有任何区别, 但是 如果是对象的话有区别ref 是可以进行 响应式点击的,shallowRef则不可以进行处理对象
- shallowReactive 只处理最外层的响应式数据
- shallowRef 只处理基本的数据类型 不进行对象的处理
- shallowReactive,readonly 限制响应式 深和浅
- toRaw 将reactive生产的响应式 转为普通的,让他变成不响应式的对象
- markRaw 让一个属性 永远不会变成响应式的 后续,我也会一步一个脚印的去总结发文~ 您也可以点个关注~ 大家一起交流互相学习!
最后,我们来聊一下如何解决情况三的二个问题!
- 问题一: 监听reactive数据 无法正确获取修改之前的值
- 问题二: 监听reactive数据 强制开启了深度监听(无法关闭)
答: 3.0官方提供的有专门的api ,不用你手动关闭,reactive 本身就是每层都监听,你要是不想深度监听那就换shallowReactive,相应的ref 对应的也是有shallowReactive的,深度监听用reactive ,只想监听第一层,内部嵌套的对象懒得管那就加个shallow就行了,性能会更高,但是缺点是更新值麻烦,因为它就管第一层,其他懒得管。
以上就是我对Vue3.0中Watch中各种情况的了解,希望可以帮助在学习Vue3.0的朋友!🌹🌹🌹 如果有不对的地方,希望指正!我会非常感谢您的! 看完记得点个赞哦~ 谢谢!🤞🤞🤞