组合式API - watch
在这里为了方便,使用的是ref 函数
作用
侦听一个或者多个数据的变化,数据变化时执行回调函数。
俩个额外参数 immediate控制立刻执行,deep开启深度侦听
基础用法侦听单个数据
步骤:
- 导入watch函数
- 执行watch函数传入要侦听的响应式数据(ref对象)和回调函数
示例
<<template>
<button @click="add">
{{ count }}
</button>
</template>
<script setup>
// 1. 导入watch
import {ref, watch } from 'vue'
const count = ref(0)
const add = () => count.value++
// 2. 调用watch 侦听变化
// count: ref参数不需要加.value
watch(count, (newVal, oldVal) => {
console.log('旧值为',oldVal,'新值为',newVal )
})
</script>
侦听多个数据
侦听多个数据,第一个参数可以改写成数组的写法
<script setup>
// 1. 导入watch
import { ref, watch } from 'vue'
const count = ref(0)
const name = ref('cp')
// 2. 调用watch 侦听变化
watch([count, name], ([newCount, newName],[oldCount,oldName])=>{
console.log(`count或者name变化了,[newCount, newName],[oldCount,oldName])
})
</script>
立即监听 immediate
在侦听器创建时立即出发回调,响应式数据变化之后继续执行回调
<script setup>
// 1. 导入watch
import { ref, watch } from 'vue'
const count = ref(0)
// 2. 调用watch 侦听变化
watch(count, (newValue, oldValue)=>{
console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
},{
immediate: true
})
</script>
组合式APIwatch监听-深度侦听-精准侦听
浅层侦听
通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep
<script setup>
// 1. 导入watch
import { ref, watch } from 'vue'
const state = ref({ count: 0 })
// 2. 监听对象state
watch(state, ()=>{
console.log('数据变化了')
})
const changeStateByCount = ()=>{
// 直接修改不会引发回调执行
state.value.count++
}
</script>
开启deep之后
<script setup>
// 1. 导入watch
import { ref, watch } from 'vue'
const state = ref({ count: 0 })
// 2. 监听对象state 并开启deep
watch(state, ()=>{
console.log('数据变化了')
},{deep:true})
const changeStateByCount = ()=>{
// 此时修改可以触发回调
state.value.count++
}
</script>
开启deep的问题: 它会递归地处理处理所有的值,无论哪个属性被修改都会触发watch回调,这可能会导致不必要的浪费。
注意 :
1. 它会遍历每个属性去监听, 性能不好!
2.任意一个属性变化都会触发
<script setup>
// 1. 导入watch
import { ref, watch } from 'vue'
// 这里有两个属性
const state = ref({ count: 0, age: 18 })
// 2. 监听对象state 并开启deep
watch(state, ()=>{
console.log('数据变化了')
},{deep:true})
const changeStateByCount = ()=>{
// 此时修改可以触发回调
state.value.count++
}
</script>
所以 , 有了下面的精确监听
精确监听
需求 : 在不开启deep 深度监听的时候也能 监听某一个属性的值 , 而且不会影响性能
watch(()=>state.value.name, (newVal, oldVal) => {
console.log('name变化了')
})