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

Vue 3.0 How to assign a prop to a ref without changing the prop

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

我试过这样做:

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

    return { user };
  }
});

但是如果我更改用户对象的值,它也会更改 apiUser 道具。我想也许使用 Object.assign 会起作用,但 ref 不再是反应性的。

在 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 方法如下,它基本上会在更新模型时进行往返。

Parent (apiUser) ->
Child(将 apiUser 克隆到用户,进行更改,发出)->
Parent(被动设置更改)->
Child(自动接收更改,并创建新克隆)

Parent

<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);
      }
   }
}

Child

<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() 它不会改变您的道具。