为啥 vuejs 子组件数据更改更新父数据也没有显式 $emit?
Posted
技术标签:
【中文标题】为啥 vuejs 子组件数据更改更新父数据也没有显式 $emit?【英文标题】:why vuejs child component data change updates parent data also without explicit $emit?为什么 vuejs 子组件数据更改更新父数据也没有显式 $emit? 【发布时间】:2018-08-24 11:04:17 【问题描述】:这是我的根元素,在数据中“预订”是一个带有网站预订的对象。 Sitebooking 对象可以具有包含名字和姓氏的对象数组。
var app = new Vue(
el: '#app',
data:
booking:
sitebooking: [
firstname: "",
lastname: ""
,
firstname: "",
lastname: ""
],
);
这是我的模板(子组件),
<template id="sitebooking_template">
<div>
<div class="row clearfix">
<div class="col-md-6">
<div class="form-group required">
<label for="firstname">First name</label>
<input class="form-control" placeholder="First name" required="" name="firstname" type="text" value="" id="firstname" v-model="newcompsitebooking.firstname">
</div>
</div>
<div class="col-md-6">
<div class="form-group required">
<label for="lastname">Last name</label>
<input class="form-control" placeholder="Last name" required="" name="lastname" type="text" value="" id="lastname" v-model="newcompsitebooking.lastname">
</div>
</div>
</div>
</div>
</template>
并且我正在循环访问父组件中的 booking.sitebooking 对象以创建多个子组件(每个站点预订将获得一个子组件)。
<div class="" id="app">
<sitebooking v-for="(val,idx) in booking.sitebooking" :key="idx" :my-sb="val"></sitebooking>
</div>
我通过“my-sb”道具传递值并分配给子组件中的本地数据。
Vue.component('sitebooking',
template: '#sitebooking_template',
props:["mySb"],
data: function ()
return
newcompsitebooking : this.mySb,
);
到目前为止一切正常,但奇怪的行为是每当我更改子组件中的值时,它也会更新父组件的数据。但是根据 vuejs 文档,子组件的更改将通过 emit 传播回父组件。但是我没有将数据发送回父级,但值仍然会在父级中自动更新。
有人可以帮忙吗?
【问题讨论】:
【参考方案1】:您正在传递一个指向 siteBooking 对象的指针。子对象可以做任何它喜欢的指针并且父对象不会做出反应,但对象及其属性仍然是共享的。
编辑克隆一个对象以创建一个新对象称为deep cloning
【讨论】:
但我将数据发送到道具并将其存储在本地数据变量中。并试图只更改本地数据,但它也会更新父数据,我不知道如何限制这个! 所有 javascript 对象都由reference
传递,您将 reference
存储在局部变量中。如果你想创建一个新对象,你必须克隆它。
感谢您的评论,您是对的。这里也有更多的讨论。 forum.vuejs.org/t/props-are-mutable-when-passed-as-an-object/…【参考方案2】:
我通过以下更改解决了这个问题。
每当我尝试将对象作为道具传递并分配给子变量时,它实际上会复制父数据的引用,这会导致问题。所以如果你这样做了,child 的变化会影响到 parent 的数据,这是不好的。
我在这里找到了一个很好的讨论,
https://forum.vuejs.org/t/props-are-mutable-when-passed-as-an-object/2525/5
解决方案
为了解决这个问题,正如@icecream_hobbit 回答中所建议的,我尝试克隆 prob obj,然后将它的新副本存储在本地数据中。
如何克隆对象
Vuejs : How to pass an object as prop and have the component update sub-objects
Is this a good way to clone an object in ES6?
我现在这样修改了我的代码,
Vue.component('sitebooking',
template: '#sitebooking_template',
props:["mySb"],
data: function ()
return
newcompsitebooking : ...this.mySb,
);
现在问题解决了。感谢@icecream_hobbit。
【讨论】:
以上是关于为啥 vuejs 子组件数据更改更新父数据也没有显式 $emit?的主要内容,如果未能解决你的问题,请参考以下文章