Vue侦听器 (watch)的使用方法及使用场景总结

在 Vue 3 的 Composition API 中,可以使用 watch 函数来设置侦听器。watch 函数允许您监听响应式状态的变化,并在特定条件下执行相应的操作。

使用方法

  • 基本用法
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';

const count = ref(0);

const increment = () => {
  count.value++;
};

// 监听 count 的变化
watch(count, (newValue, oldValue) => {
  console.log(`count 值从 ${oldValue} 变为 ${newValue}`);
});
</script>
  • 监听多个响应式状态
<script setup>
import { ref, watch } from 'vue';

const count = ref(0);
const double = ref(0);

const increment = () => {
  count.value++;
};

// 监听多个响应式状态的变化
watch([count, double], ([newCount, newDouble], [oldCount, oldDouble]) => {
  console.log(`count 变化: ${oldCount} -> ${newCount}`);
  console.log(`double 变化: ${oldDouble} -> ${newDouble}`);
});
</script>
  • 监听对象内部属性的变化
<script setup>
import { reactive, watch } from 'vue';

const state = reactive({
  user: {
    name: 'John',
    age: 30
  }
});

// 监听对象内部属性的变化
watch(() => state.user.name, (newName, oldName) => {
  console.log(`用户名从 ${oldName} 变为 ${newName}`);
});
</script>
  • 配置选项
<script setup>
import { ref, watch } from 'vue';

const count = ref(0);

// 配置选项:immediate 表示立即执行回调函数
watch(count, (newValue, oldValue) => {
  console.log(`count 值从 ${oldValue} 变为 ${newValue}`);
}, { immediate: true });
</script>

使用场景总结

  1. 响应式状态变化时的操作:当某个响应式状态变化时,执行相应的操作,如更新 UI 或者触发其他函数。

  2. 异步操作管理:处理异步数据或依赖关系复杂的场景,例如在异步请求返回后更新状态。

  3. 计算属性依赖管理:监听多个响应式状态,根据变化计算派生状态的值。

  4. 表单验证:监听表单输入字段的变化,实时验证输入的有效性或格式。

  5. 路由变化监听:在路由变化时执行特定的逻辑,例如切换页面时的数据加载或权限控制。

  6. 状态持久化:监听状态变化,并将其持久化到本地存储或后端服务器,确保用户数据的保存和恢复。

  7. 动态加载数据:监听某个状态的变化,触发数据的动态加载或刷新。

总结

通过 watch 函数,可以更加精细地控制 Vue 应用中状态的变化,并根据变化执行对应的逻辑,从而实现更加灵活和响应式的应用程序。

完整代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 3 Watch Example in HTML</title>
    <script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
</head>

<body>
    <div id="app">
        <div>
            <p>User: {{ user.name }}</p>
            <p v-if="isAdmin">You are an admin!</p>
        </div>
    </div>

    <script>
        // 模拟 Vue 3 Composition API 的效果
        const { ref, watch } = Vue;

        const user = ref({ id: 1, name: 'Alice', isAdmin: false });

        // 监听 isAdmin 变化,并执行相关操作
        // 监测 user.value.isAdmin 的变化,并在 isAdmin 变为 true 时执行异步操作 updateUser。
        watch(() => user.value.isAdmin, (newVal, oldVal) => {
            if (newVal) {
                // 异步更新用户信息
                updateUser();
            }
        });

        async function updateUser () {
            // 模拟异步更新用户信息
            await fetchUserInfo(user.value.id);
        }

        async function fetchUserInfo (userId) {
            // 模拟发起 API 请求获取用户信息
            // 这里可以实际调用后端 API 获取最新的用户信息
            // 在这个示例中,直接更新用户名称
            user.value.name = 'Updated Name';
        }

        // 创建 Vue 应用
        const app = Vue.createApp({
            setup () {
                return {
                    user,
                    isAdmin: user.value.isAdmin
                };
            }
        });

        // 挂载应用
        app.mount('#app');
    </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 3 Watch Route Example in HTML</title>
    <script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
    <script src="https://unpkg.com/vue-router@4.0.12/dist/vue-router.global.prod.js"></script>
</head>

<body>
    <div id="app">
        <div>
            <p>Loading data for ID: {{ routeParams.id }}</p>
        </div>
    </div>
    <!-- computed 适合用于计算或者派生出一个新的值,它自动响应依赖的数据变化。
watch 更适合用于监控特定数据的变化,执行一些更为复杂的逻辑,比如异步操作、依赖数据的变化后的数据更新等场景。 -->
    <script>
        // 模拟 Vue 3 Composition API 的效果
        const { ref, watch } = Vue;
        const { createRouter, createWebHistory } = VueRouter;

        const routeParams = ref({ id: null });

        // 模拟 useRoute() 的行为
        const router = createRouter({
            history: createWebHistory(),
            routes: [
                { path: '/example/:id', component: {} }
            ]
        });

        router.currentRoute.value.params = { id: 'initialId' };

        // 监听路由参数变化,重新加载数据
        watch(() => router.currentRoute.value.params.id, async (newId, oldId) => {
            // 根据新的 ID 加载数据
            await fetchData(newId);
        });

        async function fetchData (id) {
            // 模拟根据 ID 加载数据的操作
            // 这里可以实际调用后端 API 根据 ID 加载数据
            // 在这个示例中,直接更新路由参数
            routeParams.value.id = id;
        }

        // 创建 Vue 应用
        const app = Vue.createApp({
            setup () {
                return {
                    routeParams
                };
            }
        });

        // 挂载应用
        app.use(router);
        app.mount('#app');
    </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值