Vue3学习(组合式API——Watch侦听器、watchEffect()详解)

目录

一、Watch侦听器。

(1)侦听单个数据。

(2)侦听多个数据。(数组写法?!)

(3)immediate参数。(立即执行回调)

(3)deep参数。(深层监视)

使用deep开启深度侦听监视。(不仅监听对象的地址,还会监听对象的所有子属性变化)

(4)精确侦听对象(ref、reactive)的某个属性。(固定写法的简单回调:()=>xx对象)


一、Watch侦听器。

  • 官方解释:在组合式 API 中,使用 watch 函数在每次响应式状态发生变化时触发回调函数。
  • 基本作用:侦听一个或者多个数据的变化,数据变化时执行回调函数。其中有两个额外的参数:immediate(立即执行)、deep(深度侦听)。
(1)侦听单个数据。
  • 基本语法:watch(ref对象,(newValue,oldValue)=>{ ... })。
  • 代码示例。
html 复制代码
<!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)=>{ ... })。
  • 代码示例。
html 复制代码
<!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参数。(立即执行回调)
  • 基本说明:在侦听器创建时------立即触发回调,响应式数据变化之后继续执行回调。
  • 代码示例。(一进页面里面执行回调!)
html 复制代码
<!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开启深度侦听监视。(不仅监听对象的地址,还会监听对象的所有子属性变化)
  • 代码示例。
html 复制代码
<!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创建的对象)
html 复制代码
<!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()简单案例演示。
  • 代码。
html 复制代码
<!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>
  • 效果。



相关推荐
山河木马10 小时前
矩阵专题2-怎么创建视图矩阵(uViewMatrix)
javascript·webgl·计算机图形学
小林攻城狮10 小时前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦10 小时前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer10 小时前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队11 小时前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY11 小时前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
远航_11 小时前
OpenSpec 完整详细介绍
前端·后端
召钱熏11 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
SkyWalking中文站11 小时前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控
cidy_9811 小时前
Dify 操作教程:工作流编排 & Chat 对话编排
前端·工作流引擎