admin管理员组文章数量:1180451
In my parent vue component I have a user
object.
If I pass that user object to a child component as a prop:
<child :user="user"></child>
and in my child component I update user.name
, it will get updated in the parent as well.
I want to edit the user object in child component without the changes being reflected in the user object that is in parent component.
Is there a better way to achieve this than cloning the object with: JSON.parse(JSON.stringify(obj))
?
In my parent vue component I have a user
object.
If I pass that user object to a child component as a prop:
<child :user="user"></child>
and in my child component I update user.name
, it will get updated in the parent as well.
I want to edit the user object in child component without the changes being reflected in the user object that is in parent component.
Is there a better way to achieve this than cloning the object with: JSON.parse(JSON.stringify(obj))
?
4 Answers
Reset to default 28You don't have to use the JSON
object.
const child = {
props:["user"],
data(){
return {
localUser: Object.assign({}, this.user)
}
}
}
Use localUser
(or whatever you want to call it) inside your child.
Edit
I had modified a fiddle created for another answer to this question to demonstrate the above concept and @user3743266 asked
I'm coming to grips with this myself, and I'm finding this very useful. Your example works well. In the child, you've created an element in data that takes a copy of the prop, and the child works with the copy. Interesting and useful, but... it's not clear to me when the local copy gets updated if something else modifies the parent. I modified your fiddle, removing the v-ifs so everything is visible, and duplicating the edit component. If you modify name in one component, the other is orphaned and gets no changes?
The current component looks like this:
Vue.component('edit-user', {
template: `
<div>
<input type="text" v-model="localUser.name">
<button @click="$emit('save', localUser)">Save</button>
<button @click="$emit('cancel')">Cancel</button>
</div>
`,
props: ['user'],
data() {
return {
localUser: Object.assign({}, this.user)
}
}
})
Because I made the design decision to use a local copy of the user, @user3743266 is correct, the component is not automatically updated. The property user
is updated, but localUser
is not. In this case, if you wanted to automatically update local data whenever the property changed, you would need a watcher.
Vue.component('edit-user', {
template: `
<div>
<input type="text" v-model="localUser.name">
<button @click="$emit('save', localUser)">Save</button>
<button @click="$emit('cancel')">Cancel</button>
</div>
`,
props: ['user'],
data() {
return {
localUser: Object.assign({}, this.user)
}
},
watch:{
user(newUser){
this.localUser = Object.assign({}, newUser)
}
}
})
Here is the updated fiddle.
This allows you full control over when/if the local data is updated or emitted. For example, you might want to check a condition before updating the local state.
watch:{
user(newUser){
if (condition)
this.localUser = Object.assign({}, newUser)
}
}
As I said elsewhere, there are times when you might want to take advantage of objects properties being mutable, but there are also times like this where you might want more control.
in the above solutions, the watcher won't trigger at first binding, only at prop change. To solve this, use immediate=true
watch: {
test: {
immediate: true,
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
},
}
you can have a data variable just with the information you want to be locally editable and load the value in the created method
data() {
return { localUserData: {name: '', (...)}
}
(...)
created() {
this.localUserData.name = this.user.name;
}
This way you keep it clear of which data you are editing. Depending on the need, you may want to have a watcher to update the localData in case the user prop changes.
According to this, children "can't" and "shouldn't" modify the data of their parents. But here you can see that if a parent passes some reactive data as a property to a child, it's pass-by-reference and the parent sees the child's changes. This is probably what you want most of the time, no? You're only modifying the data the parent has explicitly shared. If you want the child to have an independent copy of user
, you could maybe do this with JSON.parse(JSON.stringify()) but beware you'll be serializing Vue-injected properties. When would you do it? Remember props are reactive, so the parent could send down a new user at any time, wiping out local changes?
Perhaps you need to tell us more about why you want the child to have it's own copy? What is the child going to do with its copy? If the child's user is derived from the parent user in some systematic way (uppercasing all text or something), have a look at computed properties.
本文标签: javascriptVueJS right way to edit prop without changing parent dataStack Overflow
版权声明:本文标题:javascript - VueJS right way to edit prop without changing parent data - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738204129a2068530.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论