Vue3中setup里怎么监听props变化?

打工人春萍 阅读 66

我刚从Vue2转到Vue3,现在在setup函数里用props传值,但发现props变了组件没反应。之前在Vue2里用watch可以直接监听,现在在setup里试了watch(props.xxx, ...)却报错说不能直接监听解构出来的值,这到底该怎么写才对?

我试过把整个props传给watch,但又不知道具体哪个属性变了,感觉很麻烦。有没有简洁又正确的写法?

import { watch } from 'vue'

export default {
  props: ['userId'],
  setup(props) {
    // 这样写会报错:Cannot destructure property 'userId' of 'props' as it is not reactive
    const { userId } = props
    watch(userId, (newVal) => {
      console.log('userId changed:', newVal)
    })
  }
}
我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
Code°爱景
问题在于你直接解构了 props,这会让 userId 失去响应性。Vue3 里正确的做法是用 getter 函数形式:

import { watch } from 'vue'

export default {
props: ['userId'],
setup(props) {
watch(() => props.userId, (newVal) => {
console.log('userId changed:', newVal)
})
}
}


写成 () => props.userId 这种函数形式,watch 会自动追踪响应式依赖,每次 props.userId 变化都会触发。

如果你的组件有多个 props 要监听,还可以用 watch 的第三个参数加 deep: true 深度监听整个 props 对象,或者分别写多个 watch。

另一个思路是用 toRefs 把整个 props 转成响应式引用,这样解构出来的每个属性依然保持响应:

import { watch, toRefs } from 'vue'

export default {
props: ['userId'],
setup(props) {
const { userId } = toRefs(props)
watch(userId, (newVal) => {
console.log('userId changed:', newVal)
})
}
}


不过说实话,第一种 getter 函数写法最简洁,一般用这个就够了。
点赞
2026-03-19 23:06
一增芳
一增芳 Lv1
问题在于你不能直接解构props,解构会丢失响应性。Vue3里监听props的正确姿势是用函数形式:

import { watch } from 'vue'

export default {
props: ['userId'],
setup(props) {
// 用箭头函数返回要监听的值
watch(() => props.userId, (newVal, oldVal) => {
console.log('userId changed:', newVal)
})
}
}


如果你有多个props要监听,可以用 watchEffect 或者同时写多个 watch

import { watch, watchEffect } from 'vue'

export default {
props: ['userId', 'userName'],
setup(props) {
// 监听单个
watch(() => props.userId, (newVal) => {
console.log('userId变了:', newVal)
})

// 监听多个
watch([() => props.userId, () => props.userName], ([newId, newName], [oldId, oldName]) => {
console.log('user变化了:', newId, newName)
})

// 或者用 watchEffect 自动收集依赖
watchEffect(() => {
console.log('props变化了:', props.userId, props.userName)
})
}
}


还有一种情况,如果你确实想解构出来用,可以用 toRefs 把整个props转成响应式的ref:

import { watch, toRefs } from 'vue'

export default {
props: ['userId'],
setup(props) {
const { userId } = toRefs(props)
// 这样userId是个ref,可以直接监听
watch(userId, (newVal) => {
console.log('userId changed:', newVal)
})
}
}


不过说实话,第一种写法最简洁直接,一般情况下用 watch(() => props.xxx) 就够了。
点赞
2026-03-16 15:02