踩了一个基础 知识的坑

今在开发一个循环增加select 的时候,出现了v-model绑定到相同对象,当一个select改变其他也会随之改变的问题

页面操作,1、选择其中一个select
在这里插入图片描述

2、当选择后发现上下两个select 也随之选中为了同样的值
在这里插入图片描述


Think think why … ,修改某一个select 其他两个也会同着更改!


来过过代码找找问题—//

html是这样的

 <el-form-item
            label="推送消息类型"
          >
            <div v-for="(hItem,index) in pushSecondTypeOfHour" :key="index" class="items-second-type">
              <el-select v-model="hItem.hModelVal">
                <el-option
                  v-for="item in hItem.houseList"
                  :key="item.value+'-h'"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <el-select v-model="hItem.tModelVal">
                <el-option
                  v-for="item in hItem.temperList"
                  :key="item.value+'-t'"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <el-select v-model="hItem.maxModelVal">
                <el-option
                  v-for="item in hItem.maxList"
                  :key="item.value+'-m'"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <i v-show="pushSecondTypeOfHour.length>1&&index!==pushSecondTypeOfHour.length-1" class="el-icon-minus rec-second-msg" @click="redcSecondBtn" />
              <i v-show="index===pushSecondTypeOfHour.length-1" class="el-icon-plus add-second-msg" @click="addSecondType" />
              <span v-show="index===pushSecondTypeOfHour.length-1" class="add-second-msg-txt">添加类型1/3</span>
            </div>
          </el-form-item>
            

js是这样的

<script>

export default {
data(){
	return{
      pushSecondTypeOfHourOption: {
        houseList: [
          { label: '1小时', value: 1 },
          { label: '3小时', value: 3 },
          { label: '6小时', value: 6 },
          { label: '12小时', value: 12 },
          { label: '24小时', value: 24 }
        ],
        temperList: [
          { label: '降温', value: 1 },
          { label: '降水', value: 3 },
          { label: '风', value: 4 }
        ],
        maxList: [
          { label: '最大值', value: 1 },
          { label: '最小值', value: 3 },
          { label: '平均值', value: 4 },
          { label: '累计值', value: 5 }
        ],
        hModelVal: 1,
        tModelVal: 1,
        maxModelVal: 1
      },
      pushSecondTypeOfHour: []
	}
  },
    created() {
    this.pushSecondTypeOfHour.push(this.pushSecondTypeOfHourOption)
  },
    methods: {
    // 增加消息类型
    addSecondType() {
      this.pushSecondTypeOfHour.push(this.pushSecondTypeOfHourOption)
      console.log(this.pushSecondTypeOfHour)
    },
    // 删除
    redcSecondBtn() {
      this.pushSecondTypeOfHour.pop()
    }
   }
}

后来才发现原来是这里addSecondType()方法直接用pushSecondTypeOfHour push 了这个this.pushSecondTypeOfHourOption 对象


这就意味着,数组里所有元素的内存地址都指向了同一个pushSecondTypeOfHourOption 对象, 而后来的v-model 绑定自然也就在同一个对象上了,当改变时几个select 所选中的值都相同自然就不奇怪了


最后修改代码

1、修改pushSecondTypeOfHourOption 定义

将data中的pushSecondTypeOfHourOption 移动到 最外层,定义为一个常量

const TYPE_OPTIONS = {
  houseList: [
    { label: '1小时', value: 1 },
    { label: '3小时', value: 3 },
    { label: '6小时', value: 6 },
    { label: '12小时', value: 12 },
    { label: '24小时', value: 24 }
  ],
  temperList: [
    { label: '降温', value: 1 },
    { label: '降水', value: 3 },
    { label: '风', value: 4 }
  ],
  maxList: [
    { label: '最大值', value: 1 },
    { label: '最小值', value: 3 },
    { label: '平均值', value: 4 },
    { label: '累计值', value: 5 }
  ],
  hModelVal: 1,
  tModelVal: 1,
  maxModelVal: 1
}
export default {
// ........
2、再修改methods
  created() {
    // this.handlerFilter()
    this.pushSecondTypeOfHour.push(TYPE_OPTIONS)
  },
  methods: {
    // 增加消息类型
    addSecondType() {
      // 拷贝一份值
      const typeOptions = Object.assign({}, TYPE_OPTIONS)
      this.pushSecondTypeOfHour.push(typeOptions)
      console.log(this.pushSecondTypeOfHour)
    }
  }

addSecondType() 使用Object.assign()进行对象拷贝,再将其添加到pushSecondTypeOfHour数组中,确保数组元素不是同一个对象

在这里插入图片描述
ok 问题解决,没想还踩了个基础知识的坑

这里借用相关文章补补基础知识

                             JS中的基本类型和引用类型

基本类型:undefined、null、string、number、boolean、symbo(ES6)

普通基本类型:undefined、null、symbol(ES6)
特殊基本包装类型:string、number、boolean

引用类型:Object、Array、RegExp、Date、Function

区别:引用类型值可添加属性和方法,而基本类型则不可以。

1、基本类型

  1. 基本类型的变量是存放在栈内存(Stack)里的
  2. 基本数据类型的值是按值访问的
  3. 基本类型的值是不可变的
  4. 基本类型的比较是它们的值的比较

2、引用类型

  1. 引用类型的值是保存在堆内存(Heap)中的对象(Object)
  2. 引用类型的值是按引用访问的
  3. 引用类型的值是可变的
  4. 引用类型的比较是引用(对象本身)的比较

基本类型的赋值其实就是将变量的值复制一份给另一个变量,当一个变量值做操作时并不会影响到其他变量

引用类型的赋值其实是将对象保存在栈区地址的指针(内存地址)赋值给另一个变量,赋值后等同于这两个变量都指向了同一块内存地址,因此当一个变量赋值给另一个时,两个变量指向的是同一个对象(及内存地址),任何的操作都相互影响。

原文地址:https://www.cnblogs.com/dengxiaoning/p/13336782.html