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)=>{ ... })
  • 代码示例。
<!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>
  • 效果。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁岁岁平安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值