简体   繁体   English

更改 model 属性值正在更改其他 object 中的相同属性

[英]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我的datamodelsdefaults中有 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM