[英]changing model property value is changing the same property in other object
im new to vue, i want user to be able to add some specific social media links to the page and edit some properties like it's text我是 vue 的新手,我希望用户能够向页面添加一些特定的社交媒体链接并编辑一些属性,比如它的文本
i have 2 objects in my data
, models
and defaults
我的
data
、 models
和defaults
中有 2 个对象
defaults contains selectable option for social media links and their initial values默认值包含社交媒体链接及其初始值的可选选项
basically i copy the default value into models and let the user customize the model via inputs基本上我将默认值复制到模型中,让用户通过输入自定义 model
data () {
return {
models : [] ,
defaults : {
twitter : { id : null , placeholder : 'my twitter' , icon : 'twitter' , text : null , 'link' : null } ,
instagram : { id : null , placeholder : 'my instagram' , icon : 'instagram' , text : null , 'link' : null } ,
tiktok : { id : null , placeholder : 'my tiktok' , icon : 'tiktok' , text : null , 'link' : null } ,
} ,
}
} ,
so there a select menu for user to select which social he wants to add to the page所以有一个 select 菜单供用户使用 select 他想要添加到页面的社交
Select :
<ul >
<li v-for="(social, index ) in defaults" :key="index">
<a @click="appendSocial(index)">
{{ index }}
</a>
</li>
</ul>
here is my @click="appendSocial(index)"
function这是我的
@click="appendSocial(index)"
function
appendSocial(type){
let typedefault = this.defaults[type];
this.models.push(typedefault)
},
and finally i show my models to user and provide an input for editing it's text via v-model
最后我向用户展示我的模型并提供一个输入以通过
v-model
编辑它的文本
<div v-for="(model, index) in models" v-bind:key="model.id">
<a class="button-preview">
{{ model.text === null ? model.placeholder : model.text }}
</a>
<label>Text</label>
<input type="text" v-model="model.text" :key="index" :placeholder="model.placeholder">
</div>
so here is the problem, for some reason changing the models
properties will change the same property in defaults
... and changing defaults
properties will change the same property models
!!所以这是问题所在,由于某种原因更改
models
属性会更改defaults
属性中的相同属性......并且更改defaults
属性将更改相同的属性models
!
like if i add a twitter menu to the page and change it's text (model.text) to abc
via v-model... it will also change defaults.twitter.text
to abc
就像我将 twitter 菜单添加到页面并通过 v-model 将其文本(model.text)更改为
abc
一样......它也会将defaults.twitter.text
更改为abc
to better demonstrate the problem i've added some console log to my appendSocialfunction为了更好地演示问题,我在 appendSocialfunction 中添加了一些控制台日志
appendSocial(type){
let typedefault = this.defaults[type];
console.log(`-------- default object for ${type} -----------`);
console.log(typedefault);
this.addElement(typedefault);
},
here is the result这是结果
1 - i've selected a twitter link and added to my models, you can see defaults.twitter.text
is null
1 - 我选择了一个 twitter 链接并添加到我的模型中,你可以看到
defaults.twitter.text
。twitter.text 是null
2 - i've change my model.text
(i suppose it would be models[0].text
) to abc
2 - 我已经将我的
model.text
(我想它会是models[0].text
)更改为abc
3 - i've added another twitter link to my page... this time defaults.twitter.text
is also abc
3 - 我添加了另一个 twitter 链接到我的页面...这次是
defaults.twitter.text
。twitter.text 也是abc
also changing defaults properties will effect all the models the has been getting their value from that default object更改默认属性也会影响从该默认 object 获取其值的所有模型
like if i change the defaults.instagram.text
to xyz
all my models which have got their initial values from defaults.instagram
will also change their text to xyz
就像如果我将
defaults.instagram.text
更改为xyz
我所有从defaults.instagram
获得初始值的模型也会将其文本更改为xyz
it's like they are referencing each other, but i haven't passed the value between 2 objects by reference就像它们相互引用一样,但我没有通过引用在 2 个对象之间传递值
im not sure what's happening here and how can i prevent this?我不确定这里发生了什么,我该如何防止这种情况?
This is because这是因为
let typedefault = this.defaults[type];
this.models.push(typedefault)
Is storing the reference to the object into your this.models array.将对 object 的引用存储到您的 this.models 数组中。 And so if you mutate the element, you're by default changing the base object.
因此,如果您改变元素,默认情况下您将更改基本 object。 A quick and dirty way of doing a deep clone is the following.
以下是进行深度克隆的一种快速而肮脏的方法。
let typedefault = this.defaults[type];
let clonedObj = JSON.parse(JSON.stringify(typedefault));
this.models.push(clonedObj)
Note: Lodash library does have a proper deep clone functionality.注意:Lodash 库确实具有适当的深度克隆功能。 https://www.geeksforgeeks.org/lodash-_-clonedeep-method/
https://www.geeksforgeeks.org/lodash-_-clonedeep-method/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.