Vue 3.0如何在不改变属性的情况下将属性分配给引用

aemubtdh  于 2023-05-01  发布在  Vue.js
关注(0)|答案(4)|浏览(168)

我从父组件发送一个prop:user。现在在子组件中,我想复制它,而不改变prop的值。
我试着这样做:

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

    return { user };
  }
});

但是如果我改变了user对象的值,它也会改变apiUser属性。我想也许使用Object.assign会工作,但然后参考是不是React了。
在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.
  }
};

感谢@ buttons的评论,导致了答案。
const user = reactive({ ...props.apiUser });

pgpifvop

pgpifvop1#

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

使用composition API,我们有toRef API,允许您从任何source reactive object创建副本。因为props对象是reactive,所以你使用toRef(),它不会改变你的prop。

nbewdwxp

nbewdwxp2#

这就是你要找的: www.example.com
在将 prop 添加到的位置创建数据

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

或者如果你使用API composition:

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

您还可以考虑使用计算方法(参见上面的链接文档部分)或v-model。
请注意,标记的解决方案https://stackoverflow.com/a/67820271/2311074不起作用。如果您尝试更新user,您将在控制台上看到只读错误。如果你不需要修改user,你可以直接使用prop。

vc9ivgsu

vc9ivgsu3#

正如在评论部分所讨论的,在这些情况下,我个人喜欢的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);
      }
   }
}

抱歉任何类型的小姐

pkln4tw6

pkln4tw64#

通过这种方法
const userCopy = toRef(props, 'apiUser')
所创建的ref将尝试在改变时改变 prop 并产生警告。
将refMap到prop并且不引起prop突变的正确方法如下

const userCopy = ref();

watchEffect(() => (userCopy.value = props.apiUser));

相关问题