如果我观看解构的道具,Vue 3 手表将无法工作

Posted

技术标签:

【中文标题】如果我观看解构的道具,Vue 3 手表将无法工作【英文标题】:Vue 3 watch doesn’t work if I watch a destructured prop 【发布时间】:2021-03-03 16:26:53 【问题描述】:

我正在尝试在 Vue 3 中观看道具,但奇怪的是,当我对其进行解构时,观察者不起作用。但如果不进行解构,它会按预期工作。我在这里错过了什么?

附言我正在使用 Vue 3 + Vite

这不起作用

export default 
    props: 
        modelValue: 
            type: Boolean,
            default: false,
        ,
    ,

    setup( modelValue , context)
    
        watch(() => modelValue, (newValue, oldValue) => 
            console.log(newValue)
        )
    ,

但如果我不解构它,那么它会起作用

setup(props, context) 
    watch(() => props.modelValue, (newValue, oldValue) => 
        console.log(newValue)
    )

【问题讨论】:

您不需要引用您的代理。因此,如果属性发生变化,代理可以拦截。通过解构,你将你的解构属性分配给一个变量,你失去了引用 【参考方案1】:

props 传递到 setup 是 reactive 对象,并且所有反应都与对象本身周围的代理紧密相关。

如果您获取此类对象的属性值,您会得到:

    对象(如果值是对象),它也是响应式的 本身不能反应的值(例如整数)

而解构只是赋值:

const   modelValue  = props

...等同于:

const modelValue = props.modelValue 

您可以按照docs 中的说明使用toRefs

export default 
    props: 
        modelValue: 
            type: Boolean,
            default: false,
        ,
    ,

    setup(props, context)
    
        let  modelValue  = toRefs(props)

        watch(modelValue, (newValue, oldValue) => 
            console.log(newValue)
        )
    ,

现在modelValue 是ref,所以它可以作为watch 的第一个参数传递(不需要函数),并且在大多数地方你必须使用modelValue.Value 来获取它的值

【讨论】:

哦,你救了我的命!谢谢,我不知道我需要像这样将 props 转换为 refs。 如果您将props 对象作为一个整体传递,则您不需要。但是,如果您想将对象拆分为更小的部分并保持“部分”的反应性(同样适用于任何 reactive 对象)【参考方案2】:

解构props 将导致值失去反应性。 (vue/no-setup-props-destructure)

link to the docs rule

因此,您可以改为在 watch 中使用解构,如下所示:

watch(() => 
  const  modelValue  = props;
  console.log(modelValue);
);

【讨论】:

以上是关于如果我观看解构的道具,Vue 3 手表将无法工作的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Vue 路由器传递组件中的道具

如何使用 Inertia Js、Vue 和 Laravel 重新加载持久布局或观看道具

无法在 Vue3 中传递多个道具

从 Vue CLI(Vue 3)迁移到 Vite:未捕获(承诺中)类型错误:无法解构“未定义”的属性“默认”,因为它未定义

Vue 3 道具未通过

必须使用解构道具分配问题