微耽
15.15MB · 2025-11-05
在 Vue3 中,watch 的第三个参数是一个 配置选项对象(可选),用于精细控制监听行为。它支持多个属性,各自对应不同的功能,核心作用是调整监听的触发时机、深度监听、防抖节流等逻辑。以下是完整的配置属性及详细说明:
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
// 初始渲染时立即执行一次,之后 count 变化时再执行
watch(count, (newVal) => {
console.log('count 值:', newVal) // 初始输出 0,后续修改时输出新值
}, { immediate: true })
</script>
<script setup>
import { ref, watch } from 'vue'
const user = ref({ name: '张三', info: { age: 20 } })
// 监听 user 内部属性变化(需 deep: true)
watch(user, (newUser) => {
console.log('age 变化:', newUser.info.age) // 修改 user.value.info.age 时触发
}, { deep: true })
// 触发监听:修改嵌套属性
setTimeout(() => {
user.value.info.age = 21
}, 1000)
</script>
| 取值 | 执行时机 | 场景示例 |
|---|---|---|
| 'pre'(默认) | 组件更新 之前 执行 | 需在 DOM 更新前修改数据(避免 DOM 闪烁) |
| 'post' | 组件更新 之后 执行(DOM 已更新) | 需操作更新后的 DOM(如获取元素尺寸、滚动位置) |
| 'sync' | 被监听值变化时 同步立即执行 | 需实时响应变化(极少用,可能影响性能) |
<template>
<div ref="box" :style="{ width: `${count * 100}px` }"></div>
</template>
<script setup>
import { ref, watch } from 'vue'
const count = ref(1)
const box = ref(null)
// 回调在 DOM 更新后执行,可获取最新的元素宽度
watch(count, () => {
console.log('box 宽度:', box.value.offsetWidth) // 正确输出更新后的宽度
}, { flush: 'post' })
// 触发监听:修改 count
setTimeout(() => {
count.value = 2
}, 1000)
</script>
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
// 仅在 count 第一次变化时触发(之后再修改不触发)
watch(count, (newVal) => {
console.log('count 首次变化:', newVal) // 仅输出 1(第一次修改时)
}, { once: true })
// 触发两次修改
setTimeout(() => { count.value = 1 }, 1000)
setTimeout(() => { count.value = 2 }, 2000) // 无输出
</script>
<template>
<input v-model="keyword" placeholder="搜索...">
</template>
<script setup>
import { ref, watch } from 'vue'
const keyword = ref('')
// 输入停止 500ms 后才执行回调(避免输入时频繁触发)
watch(keyword, (newVal) => {
console.log('搜索关键词:', newVal) // 输入停止 500ms 后输出
}, { debounce: 500 })
</script>
<script setup>
import { ref, watch } from 'vue'
const scrollTop = ref(0)
// 监听滚动位置,每隔 300ms 最多执行一次
window.addEventListener('scroll', () => {
scrollTop.value = window.scrollY
})
watch(scrollTop, (newVal) => {
console.log('滚动位置:', newVal) // 每 300ms 输出一次
}, { throttle: 300 })
</script>
| 属性名 | 类型 | 默认值 | 核心作用 |
|---|---|---|---|
| immediate | boolean | false | 初始渲染时是否立即执行回调 |
| deep | boolean | false | 是否深度监听引用类型内部属性变化 |
| flush | string | 'pre' | 回调执行时机(pre/post/sync) |
| once | boolean | false | 是否只触发一次回调(触发后停止监听) |
| debounce | number | undefined | 防抖延迟(ms),多次变化仅最后一次执行 |
| throttle | number | undefined | 节流间隔(ms),高频变化时限制执行频率 |