文章目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、vue2写法
<template>
<h1>watch</h1>
求和:{{num}}
<button @click="num++">点我+1</button>
<br>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'Demo',
watch:{
// num(newvalue,oldvalue){
// console.log(newvalue,oldvalue);
// }
num:{
immediate:true,
deep:true,
handle(newvalue,oldvalue){
console.log('num变化了',newvalue,oldvalue);
}
}
},
setup(){
//数据
let num=ref(0)
//返回一个对象(常用)
return {
num
}
}
}
</script>
二、vue3写法
情况一:监视ref所定义的一个响应式数据
代码如下(示例):
<template>
<h1>watch</h1>
求和:{{num}}
<button @click="num++">点我+1</button>
<hr>
年龄:{{ age }}
<button @click="age++">年龄+1</button>
<br>
</template>
<script>
import {ref,watch} from 'vue'
export default {
name: 'Demo',
setup(){
//数据
let num=ref(0)
let age=ref(18)
// watch(num,(newValue,oldValue)=>{
// console.log('sum变了',newValue,oldValue)
// },{immediate:true})
//返回一个对象(常用)
return {
num
}
},
}
</script>
情况二:监视ref所定义的多个响应式数据
代码如下(示例):
<template>
<h1>watch</h1>
求和:{{num}}
<button @click="num++">点我+1</button>
<hr>
年龄:{{ age }}
<button @click="age++">年龄+1</button>
<br>
</template>
<script>
import {ref,watch} from 'vue'
export default {
name: 'Demo',
setup(){
//数据
let num=ref(0)
let age=ref(18)
//情况二:监视ref所定义的多个个响应式数据
watch(num,(newValue,oldValue)=>{
console.log('sum变了',newValue,oldValue)
},{immediate:true})
watch(age,(newValue,oldValue)=>{
console.log('age',newValue,oldValue)
},{immediate:true})
//返回一个对象(常用)
return {
num,age
}
},
}
</script>
watch也可以简写
情况三:监视reactive所定义的一个响应式数据的全部属性
注: 1.注意:此处无法正确的获取oldValue
2.注意:强制开启了深度监视(deep配置无效)
<template>
<h1>watch</h1>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2>薪资:{{person.job.j1.salary}}K</h2>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
<button @click="person.job.j1.salary++">涨薪</button>
</template>
<script>
import {ref,watch,reactive} from 'vue'
export default {
name: 'Demo',
setup(){
//数据
let person = reactive({
name:'张三',
age:18,
job:{
j1:{
salary:20
}
}
})
watch(person,(newvalue,oldvalue)=>{
console.log(newvalue,oldvalue);
},{deep:false})
//返回一个对象(常用)
return {
person
}
},
}
</script>
情况四:监视reactive所定义的一个响应式数据中的某个属性
注:
watch可以监视数组,对象,不能检测数组或者对象中的某个属性值
watch(()=>person.name,(newValue,oldValue)=>{
console.log('person的name变化了',newValue,oldValue)
})
情况五:监视reactive所定义的一个响应式数据中的某些属性
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
console.log('person的name或age变化了',newValue,oldValue)
})
特殊情况
此处由于监视的是reactive中定义的对象中的某个属性,所以deep配置有效
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{deep:true})
三:watchEffect
watchEffect 函数的特点:- 优点:
- 会自动收集依赖,不需要手动传递侦听内容——自动侦听回调函数中使用到的响应式数据。
- 默认 immdiate 是 true,所以初始化时会立即执行。
- 缺点:
- 无法获得变化前的值(oldVal)。
watch()
是懒执行的:当数据源发生变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。
watchEffect
相当于将watch
的依赖源和回调函数合并,当任何你有用到的响应式依赖更新时,该回调函数便会重新执行。不同于watch
,watchEffect
的回调函数会被立即执行(即{ immediate: true }
)
简单来说,watchEffect 是 Vue3 中的一个响应式 API,它允许你监听响应式状态的变化,并在其发生变化时触发副作用函数。这个特性非常有用,在我们需要对响应式数据进行操作的时候,我们可以在监听到变化后马上做出反应。
<template>
<h2>当前求和为:{{sum}}</h2>
<button @click="sum++">点我+1</button>
<hr>
<h2>当前的信息为:{{msg}}</h2>
<button @click="msg+='!'">修改信息</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2>薪资:{{person.job.j1.salary}}K</h2>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
<button @click="person.job.j1.salary++">涨薪</button>
</template>
<script>
import {ref,reactive,watch,watchEffect} from 'vue'
export default {
name: 'Demo',
setup(){
//数据
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
name:'张三',
age:18,
job:{
j1:{
salary:20
}
}
})
//监视
/* watch(sum,(newValue,oldValue)=>{
console.log('sum的值变化了',newValue,oldValue)
},{immediate:true}) */
watchEffect(()=>{
const x1 = sum.value
const x2 = person.job.j1.salary
console.log('watchEffect所指定的回调执行了')
})
//返回一个对象(常用)
return {
sum,
msg,
person
}
}
}
</script>
总结
相同点
1、两者都可以监听data属性变化
2、watch 与 watchEffect 在手动停止侦听、清除副作用 (将 onInvalidate 作为第三个参数传递给回调)、刷新时机和调试方面有相同的行为。区别
1、watch需要明确监听哪个属性
2、watchEffect会根据其中的属性,自动监听其变化
3、watcheffect初始化时,一定会执行一次(收集要监听的数据,不然不知道监听的是什么),watch只有你设置了初始化监听才会监听