在写项目的时候当我们想要实时监听响应式数据的变化时候,难免会用到watch,vue3在watch使用这方面相对于vue2还是做出了一些升级,下面介绍一些注意的点,及一些问题。
(注:这里我用的是setup语法糖)。
① 情况一:监听ref所定义的一个响应式数据
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
// watch监听
let sum = ref(0)
// ① 情况一:监听ref所定义的一个响应式数据
watch(sum, (newValue,oldValue) => {
console.log(newValue,oldValue);
},{immediate:true}) // 立即监听 0,undefined
</script>
② 情况二:监听ref所定义的多个响应式数据
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
// watch监听
watch([sum,msg],(newValue,oldValue) => {
console.log(newValue,oldValue); // [sum新,msg新],[sum旧,msg旧]
}, { immediate: true }) // 立即监听 [0,'你好啊'],[]
</script>
③ 情况三:监听reactive所定义的多个响应式数据(此处无法正确的获取oldValue) ---全部
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="person.name += '-'">增长姓名</button>
<button @click="person.age++">增长年龄</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
let person = reactive({
name: '张三',
age:18
})
// watch监听
watch(person, (newValue,oldValue) => {
console.log(newValue,oldValue); // 这里的oldValue失效:如果真的需要oldValue的值就把这个值拿出去声明变量
})
</script>
情况三(在多介绍一个)通过ref定义一个对象(此处仍然无法正确的获取oldValue)因为它内部还是会求助reactive的Proxy(注意此处监听ref定义的对象需要.value哦,结构html里不需要)。------全部
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
<h2>姓名:{{ person1.name }}</h2>
<h2>年龄:{{ person1.age }}</h2>
<button @click="person1.name += '-'">增长姓名</button>
<button @click="person1.age++">增长年龄</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
let person1 = ref({
name: '张三',
age:18
})
// watch监听
watch(person1.value, (newValue,oldValue) => {
console.log(newValue,oldValue); // 这里的oldValue依然是失效:如果真的需要oldValue的值就把这个值拿出去声明变量
})
</script>
④情况四:监听reactive所定义的一个响应式数据中某个属性(这里oldValue是可以正常输出)--某一个
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
<h2>姓名:{{ person1.name }}</h2>
<h2>年龄:{{ person1.age }}</h2>
<button @click="person1.name += '-'">增长姓名</button>
<button @click="person1.age++">增长年龄</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
let person1 = ref({
name: '张三',
age:18
})
// watch监听
watch(()=>person.age, (newValue, oldValue) => {
console.log(newValue, oldValue); // 这里的oldValue好用
})
</script>
⑤情况五:监听reactive所定义的某些响应式数据中某个属性(这里oldValue是可以使用的)----某些
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
<h2>姓名:{{ person1.name }}</h2>
<h2>年龄:{{ person1.age }}</h2>
<button @click="person1.name += '-'">增长姓名</button>
<button @click="person1.age++">增长年龄</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
let person1 = ref({
name: '张三',
age:18
})
watch([()=>person.age,()=>person.name], (newValue, oldValue) => {
console.log(newValue, oldValue); // 这里的oldValue好用
})
</script>
特殊情况:(此处由于监视的是reactive定义的对象(必须是对象)的某个属性,所以deep配置有效)
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
<h2>姓名:{{ person1.name }}</h2>
<h2>年龄:{{ person1.age }}</h2>
<button @click="person1.name += '-'">增长姓名</button>
<button @click="person1.age++">增长年龄</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
let person:any = reactive({
name: '张三',
age: 18,
job: {
j1: {
salary: 20,
}
}
})
watch(()=>person.job, (newValue, oldValue) => {
console.log(newValue, oldValue); // 这里的oldValue又拿不到了
},{deep:true})
</script>
补充ref(.value 的问题):监视简单数据类型不需要.value;
监听ref对象时需要.value。
如果不想.value可以用deep:true(开启深度监听)
<template>
<div>
<!-- watch监听 -->
<h2>当前求和为:{{ sum }}</h2>
<button @click="sum++">sum++</button>
<h2>当前信息为:{{ msg }}</h2>
<button @click="msg+='!'">msg</button>
<h2>姓名:{{ person1.name }}</h2>
<h2>年龄:{{ person1.age }}</h2>
<button @click="person1.name += '-'">增长姓名</button>
<button @click="person1.age++">增长年龄</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive,watch} from 'vue'
let sum = ref(0)
let msg: any = ref('你好啊')
let person1 = ref({
name: '张三',
age:18
})
// watch监听
watch(person1, (newValue,oldValue) => {
console.log(newValue,oldValue); // 这里的oldValue依然是失效:如果真的需要oldValue的值就把这个值拿出去声明变量
},{deep:true})
</script>