VUE数组内新push的对象被修改,其他的对象属性同时被修改

代码结构:页面根据pageList这个数组里面的对象,动态渲染。有一个设置栏,上面有很多按钮对应一个个不同的模块,每次点击就会往pageList内添加对象,页面从而渲染出不同的模块,模块时可以复用的。当我添加了两个一样的模块,例如辅助区域,当我点击右侧辅助区域设置栏的时候,两个辅助区域的是一起动的!这就是问题所在!别的模块也是如此!

图片描述


图片描述


pageList默认是空;

    <!-- 根据pageList列表内部对象的status值,判断使用哪种样式模板 -->
                                    <div v-for="(item,index) in pageList" :key="index">
<!-- 辅助区域 -->
                                        <div class="support_box" v-if="item.status==1">
                                            <button @click="showIndex(item.status,index)" :style="{backgroundColor: item.supportInfo.lineBgc}">   <!--这里对应的是辅助分割线的背影颜色==》backgroundColor-->
                                                <!-- 辅助空白 -->
                                                <div v-show="item.supportInfo.supportStatus==0" class="empty_box" :style="{ backgroundColor: item.supportInfo.emptyBgc, height: item.supportInfo.emptyHeight + 'px' }"></div>
                                                <!-- 辅助线段 样式太多,只能采取对象-->
                                                <!--对应关系==》borderTopColor:线段颜色  borderTop/style/color/width:对应线段的样式颜色宽度 marginTop/bottom:对应上下边距 -->
                                                <div v-show="item.supportInfo.supportStatus==1" class="line_box" :style="{ borderTopColor: item.supportInfo.lineColor,borderTopStyle:item.supportInfo.lineStyle,borderTopColor:item.supportInfo.lineColor, borderTopWidth: item.supportInfo.lineHeight + 'px' ,marginTop: item.supportInfo.lineMargin + 'px',marginBottom: item.supportInfo.lineMargin + 'px'}"></div>
                                                <!-- 模块删除按钮 -->
                                                <div class="del_li" @click="model_del_li(index)">X</div>
                                            </button>
                                            <!-- #######辅助区域栏 #####-->
                                            <!-- 先根据status判断该显示那一种设置框,然后判断具体是哪一个的设置框,每次只显示一个 -->
                                            <div v-show="1==isShow && index==listIndex" class="support_set">
                                                <el-form label-width="80px">
                                                    <el-form-item label="辅助类型">
                                                        <el-radio-group v-model="item.supportInfo.supportStatus">
                                                            <el-radio label="0">辅助空白</el-radio>
                                                            <el-radio label="1">辅助分割线</el-radio>
                                                        </el-radio-group>
                                                    </el-form-item>
                                                    <!--          ####### 辅助空白设置栏     ############        -->
                                                    <div v-show="item.supportInfo.supportStatus==0">
                                                        <el-form-item label="背景颜色">
                                                            <el-color-picker v-model="item.supportInfo.emptyBgc"></el-color-picker>
                                                        </el-form-item>
                                                        <el-form-item label="区域高度" class="slider_box">
                                                            <el-slider class="slider_set" v-model="item.supportInfo.emptyHeight" :min="1" :max="40" show-stops>
                                                            </el-slider>
                                                            <span>{{item.supportInfo.emptyHeight}}px</span>
                                                        </el-form-item>
                                                    </div>
                                                    <!--         ###########      辅助分割线设置栏       ################           -->
                                                    <div v-show="item.supportInfo.supportStatus==1">
                                                        <el-form-item label="背景颜色">
                                                            <el-color-picker v-model="item.supportInfo.lineBgc"></el-color-picker>
                                                        </el-form-item>
                                                        <el-form-item label="线段颜色">
                                                            <el-color-picker v-model="item.supportInfo.lineColor"></el-color-picker>
                                                        </el-form-item>
                                                        <el-form-item label="线段样式">
                                                            <el-radio-group v-model="item.supportInfo.lineStyle">
                                                                <el-radio label="solid">实线</el-radio>
                                                                <el-radio label="dashed">虚线</el-radio>
                                                                <el-radio label="dotted">点状线</el-radio>
                                                            </el-radio-group>
                                                        </el-form-item>
                                                        <el-form-item label="线段高度" class="slider_box">
                                                            <el-slider class="slider_set" v-model="item.supportInfo.lineHeight" :min="1" :max="40" show-stops>
                                                            </el-slider>
                                                            <span>{{item.supportInfo.lineHeight}}px</span>
                                                        </el-form-item>
                                                        <el-form-item label="上下边距" class="slider_box">
                                                            <el-slider class="slider_set" v-model="item.supportInfo.lineMargin" :min="1" :max="40" show-stops>
                                                            </el-slider>
                                                            <span>{{item.supportInfo.lineMargin}}px</span>
                                                        </el-form-item>
                                                    </div>
                                                </el-form>
                                            </div>
                                        </div>
    { //辅助区域数据
                        status: 1,
                        title: "辅助区域1",
                        supportInfo: {
                            supportStatus: "0", //辅助类型 0:空白  1:分割线 ==》默认是辅助空白0
                            emptyBgc: "#000", //空白区域背景颜色
                            emptyHeight: "20", //空白区域高度==>不需要带px单位
                            //下面是辅助分割线区域
                            lineBgc: "#fff", //分割线背景颜色
                            lineColor: "#0099bc", //分割线线段颜色
                            lineStyle: "solid", //线段样式:实线solid  虚线dashed  点状线dotted  ==》默认实线solid
                            lineHeight: "10", //线段高度==>不需要带px单位
                            lineMargin: "10", //线段上下边距==>不需要带px单位
                        }
                    }

自己尝试的解决方法:为左侧的展示栏添加 :key="index" 为右侧的设置栏添加 :key="index" 以及每次将默认的辅助区域数据push到pageList之前为它增加一个键值对(--time:new Date()--),声明它的唯一性!
但是问题依旧,感觉像是右侧的设置栏被指向同一个数据!
下面是pageList添加逻辑的代码,allList是数组,内部是每个模块默认的数据,根据点击的index值判断应该push哪一组数据

addModel(index) {
                this.pageList.push(this.allList[index])
            },

修改了代码如下:

let data = Object.assign({}, this.allList[index]);
this.pageList.push(data)

问题依旧:
图片描述

按照诺顿大师兄的方法已经解决:

let data = Object.assign({}, JSON.parse(JSON.stringify(this.allList[index])));
this.pageList.push(data)

图片描述

阅读 7.7k
1 个回答

你可以尝试一下下边的代码

var obj = {
    a:1,
    b:2
}

var arr1 = []
arr1.push(obj)

var arr2 = [] 
arr2.push(obj)

obj.b = 3

会发现 arr1arr2中的obj.b都是3了。

原因是对象是引用类型,传递的是引用地址,所以你两个数组引用的是同一个对象,只要其中一个数组改变,就会导致对象改变,进而另一个引用的数组也会改。

解决办法就是将需要放入数组的对象先深拷贝一份,用拷贝的对象,这样就不存在引用关系了。

Object.assign({},需要push的对象)可以,用lodash中的assign也行,只要是深拷贝就行。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏