简体   繁体   English

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

[英]Vue 3.0 How to assign a prop to a ref without changing the prop

I'm sending from the parent component a prop: user .我从父组件发送一个 prop: user Now in the child component I want to make a copy of it without it changing the prop's value.现在在子组件中,我想复制它而不改变道具的值。

I tried doing it like this:我试着这样做:

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

    return { user };
  }
});

But then if I change a value of the user object it also changes the apiUser prop.但是,如果我更改用户对象的值,它也会更改 apiUser 道具。 I thought maybe using Object.assign would work but then the ref isn't reactive anymore.我想也许使用Object.assign会起作用,但是 ref 不再是反应性的。

In Vue 2.0 I would do it like this:在 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.
  }
};

Credits to @butttons for the comment that lead to the answer.归功于@buttons 的评论导致答案。

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

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

With the composition API we have the toRef API that allows you to create a copy from any source reactive object .使用组合 API,我们有toRef API,它允许您从source reactive object创建副本。 Since the props object is a reactive , you use toRef() and it won't mutate your prop.由于props对象是reactive ,因此您使用toRef()并且它不会改变您的 prop。

As discussed in comment section, a Vue 2 method that I'm personally fond of in these cases is the following, it will basically make a roundtrip when updating a model.正如评论部分所讨论的,在这些情况下我个人喜欢的 Vue 2 方法如下,它在更新模型时基本上会往返。

Parent (apiUser) ->父 (apiUser) ->
Child (clone apiUser to user, make changes, emit) ->孩子(将 apiUser 克隆到用户,进行更改,发出)->
Parent (Set changes reactively) ->父级(设置响应式更改)->
Child (Automatically receives changes, and creates new clone) 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);
      }
   }
}

Apologies for any miss types对任何错过类型的道歉

This is what you looking for:https://vuejs.org/guide/components/props.html#one-way-data-flow这就是你要找的:https ://vuejs.org/guide/components/props.html#one-way-data-flow

Create data where you add the prop to在您将道具添加到的位置创建数据

export default {
  props: ['apiUser'],
  data() {
    return {
      // user only uses this.apiUser as the initial value;
      // it is disconnected from future prop updates.
      user: this.apiUser
    }
  }
}

Or if you use api composition:或者,如果您使用 api 组合:

import {ref} from "vue";
const props = defineProps(['apiUser']);
const user = ref(props.apiUser);

You also may want to consider using computed methods (see also linked doc section from above) or v-model .您可能还需要考虑使用计算方法(另请参见上面的链接文档部分)或v-model

Please note that the marked solution https://stackoverflow.com/a/67820271/2311074 is not working.请注意,标记的解决方案https://stackoverflow.com/a/67820271/2311074不起作用。 If you try to update user you will see a readonly error on the console.如果您尝试更新user ,您将在控制台上看到只读错误。 If you don't need to modify user, you may just use the prop in the first place.如果您不需要修改用户,您可以首先使用该道具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM