[英]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.