Vue 3.0如何在不更改道具的情况下将道具分配给参考

问题描述

我正在从父组件发送一个道具:user。现在,在子组件中,我想复制它而不改变prop的值。

我试图这样做:

export default defineComponent({
  props: {
    apiUser: {
      required: true,type: Object
    }
  },setup(props) {
    const user = ref(props.apiUser);

    return { user };
  }
});

但是如果我更改用户对象的值,它也会更改apiUser属性。我以为使用Object.assign也许可以,但随后裁判不再反应了。

在Vue 2.0中,我会这样:

export default {
  props: {
     apiUser: {
       required: true,type: Object
     }
  },data() {
    return {
      user: {}
    }
  },mounted() {
    this.user = this.apiUser;
    // Now I can use this.user without changing this.apiUser's value.
  }
};

通过@butttons可获得导致答案的评论

const user = reactive({ ...props.apiUser });

解决方法

正如评论部分所述,以下是我个人喜欢的Vue 2方法,它在更新模型时基本上会往返。

父母(apiUser)->
子级(将apiUser复制到用户,进行更改,发出)->
父级(设置以反应方式更改)->
子级(自动接收更改,并创建新克隆)

父母

<template>
   <div class="parent-root"
      <child :apiUser="apiUser" @setUserData="setUserData" />
   </div>
</template>

// ----------------------------------------------------
// (Obviously imports of child component etc.)
export default {
   data() {
      apiUser: {
         id: 'e134',age: 27
      }
   },methods: {
      setUserData(payload) {
         this.$set(this.apiUser,'age',payload);
      }
   }
}

孩子

<template>
   <div class="child-root"
      {{ apiUser }}
   </div>
</template>

// ----------------------------------------------------
// (Obviously imports of components etc.)
export default {
   props: {
      apiUser: {
         required: true,type: Object
      }
   },data() {
      user: null
   },watch: {
      apiUser: {
         deep: true,handler() {
            // Whatever clone method you want to use
            this.user = cloneDeep(this.apiUser);
         }
      }
   },mounted() {
      // Whatever clone method you want to use
      this.user = cloneDeep(this.apiUser);
   },methods: {
      // Whatever function catching the changes you want to do
      setUserData(payload) {
         this.$emit('setUserData',this.user);
      }
   }
}

针对任何未命中类型的道歉

,
props: {
 apiUser: {
   required: true,type: Object
 }
},setup(props) {
   const userCopy = toRef(props,'apiUser')
}

通过组合 API,我们拥有 toRef API,允许您从任何 source reactive object 创建副本。由于 props 对象是 reactive,因此您使用 toRef() 并且它不会改变您的道具。