目录
使用deep开启深度侦听监视。(不仅监听对象的地址,还会监听对象的所有子属性变化)
(4)精确侦听对象(ref、reactive)的某个属性。(固定写法的简单回调:()=>xx对象)
一、Watch侦听器。
- 官方解释:在组合式 API 中,使用 watch 函数在每次响应式状态发生变化时触发回调函数。
- 基本作用:侦听一个或者多个数据的变化,数据变化时执行回调函数。其中有两个额外的参数:immediate(立即执行)、deep(深度侦听)。
(1)侦听单个数据。
- 基本语法:watch(ref对象,(newValue,oldValue)=>{ ... })。
- 代码示例。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> {{count}}<button @click="changeCount">count+1</button> </div> <script type="module"> import { createApp, ref, watch } from './vue.esm-browser.js' createApp({ setup() { const count = ref(0) const changeCount = () => { count.value++; } watch(count, (newValue, oldValue) => { console.log('新值:' + newValue) console.log('旧值:' + oldValue) }) return { count, changeCount } } }).mount('#app') </script> </body> </html>
- 效果。
(2)侦听多个数据。(数组写法?!)
- 基本语法:watch([ref对象1,ref对象2...],(newArr,oldArr)=>{ ... })。
- 代码示例。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> {{count}}<button @click="changeCount">count+1</button> {{nickname}}<button @click="changeNickname">改昵称</button> </div> <script type="module"> import { createApp, ref, watch } from './vue.esm-browser.js' createApp({ setup() { const count = ref(0) const nickname = ref('张三') const changeCount = () => { count.value++; } const changeNickname = () => { nickname.value = '李四' } /* //监听单个数据 watch(count, (newValue, oldValue) => { console.log('新值:' + newValue) console.log('旧值:' + oldValue) }) */ //监听多个数据 watch([count, nickname], (newArr, oldArr) => { console.log('新数组:' + newArr) console.log('旧数组:' + oldArr) }) return { count, nickname, changeCount, changeNickname } } }).mount('#app') </script> </body> </html>
- 效果。
(3)immediate参数。(立即执行回调)
- 基本说明:在侦听器创建时——立即触发回调,响应式数据变化之后继续执行回调。
- 代码示例。(一进页面里面执行回调!)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> {{count}}<button @click="changeCount">count+1</button> </div> <script type="module"> import { createApp, ref, watch } from './vue.esm-browser.js' createApp({ setup() { const count = ref(0) const changeCount = () => { count.value++; } //immediate,立即执行回调 watch(count, (newValue, oldValue) => { console.log('新值:' + newValue) console.log('旧值:' + oldValue) }, { immediate: true } ) return { count, changeCount, } } }).mount('#app') </script> </body> </html>
- 效果。
(3)deep参数。(深层监视)
- 基本说明:其中默认的watch进行浅层监视(如:const ref1 = ref(简单类型),可以直接监视)。默认的watch对于“const ref2 = ref(复杂类型)”,监视不到其内部数据的变化!
- deep:true。开启监视侦听内部数据的变化。
- 这种情况只有修改userInfo整个.value,修改了对象的地址才能侦听监视到。因为默认是浅层的。
使用deep开启深度侦听监视。(不仅监听对象的地址,还会监听对象的所有子属性变化)
- 代码示例。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> {{count}}<button @click="changeCount">count+1</button> <div>----------------------------------------------------</div> {{userInfo}}<button @click="changeUserInfo">修改userInfo</button> </div> <script type="module"> import { createApp, ref, watch } from './vue.esm-browser.js' createApp({ setup() { const count = ref(0) const userInfo = ref({ name: 'zs', age: '18' }) const changeCount = () => { count.value++; } const changeUserInfo = () => { userInfo.value.age++; } //浅层侦听 watch(userInfo, (newValue) => { console.log(newValue) }, { deep: true } ) return { count, userInfo, changeCount, changeUserInfo } } }).mount('#app') </script> </body> </html>
- 效果。
(4)精确侦听对象(ref、reactive)的某个属性。(固定写法的简单回调:()=>xx对象)
- 基本说明:在不开启deep参数的前提下,侦听某个对象的某个属性的变化,且只有该值发生变化时才执行回调!
- 代码示例。(ref创建的对象、reactive创建的对象)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> {{userInfo}}<button @click="changeUserInfo">修改userInfo</button> <div>----------------------------------------------------</div> {{userInfo2}}<button @click="changeUserInfo2">修改userInfo2</button> </div> <script type="module"> import { createApp, ref, watch, reactive } from './vue.esm-browser.js' createApp({ setup() { const userInfo = ref({ name: 'zs', age: '18' }) const userInfo2 = reactive({ name: 'ls', age: '30' }) const changeUserInfo = () => { userInfo.value.age++; } const changeUserInfo2 = () => { userInfo2.name = 'wu' } //watch侦听 watch(() => userInfo.value.age, (newValue, oldValue) => { console.log('新' + newValue) console.log('旧' + oldValue) }) watch(() => userInfo2.name, (newValue, oldValue) => { console.log('新' + newValue) console.log('旧' + oldValue) }) return { userInfo, userInfo2, changeUserInfo, changeUserInfo2 } } }).mount('#app') </script> </body> </html>
- 效果。
二、watchEffect()。
(1)基本介绍与主要特点。
- 官方解释:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
- 基本介绍:
- watchEffect 是 Vue 3 中用于响应式数据监听的 API ,属于组合式 API 。
- 它会立即执行传入的回调函数,并在其依赖的响应式数据变化时重新执行该函数。
- 主要特点:
- 自动追踪依赖:无需显式指定依赖项,watchEffect 会自动追踪在回调函数中使用的响应式数据。比如在回调中使用了某个 ref 或 reactive 定义的响应式数据,当该数据变化时,watchEffect 就能感知到并重新执行回调。
- 响应式副作用处理:专注于处理副作用,只要依赖项发生变化,就会重新执行回调函数,确保获取到最新状态。像执行 DOM 更新、发起 API 请求等操作,都可以在 watchEffect 中进行。
- 立即执行:与 watch 不同,watchEffect 会在组件初始化时就立即执行回调函数,不需要等到依赖的数据发生变化才执行。
(2)watchEffect()简单案例演示。
- 代码。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> {{count}}<button @click="increment">count++</button> </div> <script type="module"> import { createApp, ref, watchEffect } from './vue.esm-browser.js' createApp({ setup() { // 定义一个ref类型的响应式数据 const count = ref(0); // 定义一个方法用于修改响应式数据 const increment = () => { count.value++; }; // 使用watchEffect监听响应式数据变化 watchEffect(() => { //注意使用的是反引号`` console.log(`计数发生变化,当前值为: ${count.value}`); }); return { count, increment } } }).mount('#app') </script> </body> </html>
- 效果。