今在開發一個循環增加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、基本類型
- 基本類型的變量是存放在棧內存(Stack)裏的
- 基本數據類型的值是按值訪問的
- 基本類型的值是不可變的
- 基本類型的比較是它們的值的比較
2、引用類型
- 引用類型的值是保存在堆內存(Heap)中的對象(Object)
- 引用類型的值是按引用訪問的
- 引用類型的值是可變的
- 引用類型的比較是引用(對象本身)的比較
基本類型的賦值其實就是將變量的值複製一份給另一個變量,當一個變量值做操作時並不會影響到其他變量
引用類型的賦值其實是將對象保存在棧區地址的指針(內存地址)賦值給另一個變量,賦值後等同於這兩個變量都指向了同一塊內存地址,因此當一個變量賦值給另一個時,兩個變量指向的是同一個對象(及內存地址),任何的操作都會相互影響。