這個是今天遇到一個坑,因為也是第一次使用vue+element-ui開發,所以記錄一下自己遇到的一些問題。
這個問題是在開發省市區三級聯動組件的時候遇到的,具體的情況如下發的gif圖,雖然解決了問題,但是還是沒有懂是為什么這樣,有人說是element的bug,不過我覺得不像,可能是用法的問題吧,希望知道原因的博友們可以告知,現在先上下代碼;
1.首先address.json的格式是:
[
{ "name": "北京", "city":[{"name":"北京", "area":["東城區","西城區","崇文區","宣武區","朝陽區","豐台區","石景山區","海淀區","門頭溝區","房山區","通州區","順義區","昌平區","大興區","平谷區","懷柔區","密雲縣","延慶縣"]}]},
{ "name": "天津", "city":[{"name":"天津", "area":["和平區","河東區","河西區","南開區","河北區","紅橋區","塘沽區","漢沽區","大港區","東麗區","西青區","津南區","北辰區","武清區","寶坻區","寧河縣","靜海縣","薊 縣"]}]}
]
1.然后就是組件的代碼了,功能很簡單,也加了一些注釋
<template>
<div class="ad-box">
<el-select v-model="province" placeholder="選擇省" style="width: 150px;">
<el-option :label="item.name" @click.native="provinceChange(item)" :key="item.name" v-for="item in data" :value="item.name"></el-option>
</el-select>
<el-select v-model="city" placeholder="選擇市" style="width: 150px;">
<el-option :label="item.name" v-for="item in citylist" @click.native="cityChange(item)" :key="item.name" :value="item.name"></el-option>
</el-select>
<el-select v-model="area" placeholder="選擇區/鄉鎮" style="width: 150px;">
<el-option :label="item" @click.native="emitData" v-for="item in arealist" :key="item" :value="item"></el-option>
</el-select>
</div>
</template>
<script>
// 獲取地址JSON
import addressJSON from './address.json';
export default {
data() {
return {
onecetime: true,
province: '',
city: '',
area: '',
data: addressJSON,
citylist: [],
arealist: [],
}
},
props: {
address: {
type: Object,
default: function () {
return {
province: '',
city: '',
area: ''
}
}
}
},
watch: {
'address.province': function(val, oldVal) {
if (val && this.onecetime) {
this.data.map(item => {
if (item.name == this.address.province) {
this.citylist = item.city;
if (this.address.city) {
this.citylist.map(item => {
if (item.name == this.address.city) {
this.arealist = item.area;
}
})
}
return false;
}
})
this.area = this.address.area;
this.city = this.address.city;
this.province = this.address.province;
this.onecetime = false;
}
},
},
// 通過默認值獲取初始的三欄下拉列表
created() {
this.area = this.address.area;
this.city = this.address.city;
this.province = this.address.province;
},
methods: {
// 選擇省份后清空市和區
provinceChange(item) {
this.city = '';
this.area = '';
this.getList('citylist', item, 'city')
this.emitData(); //因為需求是可以不用填寫完整的,所以每填一欄上傳一次結果
},
// 選擇市后情況區/縣
cityChange(item) {
this.area = '';
this.getList('arealist', item, 'area')
this.emitData();
},
// 聯動獲取下一欄中的選項列表,參考地址的JSON格式
getList(prop, data, name) {
this[prop] = data[name];
},
// 向父級組件發送自定義事件,提交選擇結果
emitData() {
let data = {
province: this.province,
city: this.city,
area: this.area
};
this.$emit('getAddress', data);
}
}
}
</script>
<style scoped lang="scss">
.ad-box {
display: inline-block;
}
</style>
1.組件的使用方式:
//先注入組件后:
<address3 @getAddress="changeAddress" :address="{province: '福建', city: '漳州', area: '薌城區'}"></address3>
其實是很簡單的一個組件,為什么要寫這博客記錄呢,其實就是跟標題說的一樣,element-ui中的select的賦值問題:
如果 el-select 上 v-model="" 綁定的這個字段沒有事先定義好的話,而且你的option是通過請求到的數組v-for出來的話(如果option是寫死的就不會有這個問題),就會出現選擇后,select元素上無法展示,但是其實數值已經綁定上去了的后果
舉個例子:
比如 我有個 用戶信息編輯頁面, this.info通過請求獲取, banklist也是通過請求獲取銀行列表的
<el-select v-model="info.bankId" placeholder="選擇開戶銀行">
<el-option :label="item.bankName" :key="item.bankId" v-for="item in banklist" :value="item.bankId"></el-option>
</el-select>
//這時候,就會出現標題上的坑,選擇選項后,從vue dev-tools看發現值已經賦進去了,但是select上就是不顯示選中的label
//處理的方法還是 在 data中事先申明一個屬性,不要再v-model中綁定不存在的屬性就不會出現這種情況,但是現實開發中這樣又很麻煩,要多賦值一遍
2017.08.30:
回復之前的賦值無效的問題,因為之前的方式是從props拿到值后,就直接賦值給對應的屬性,但是當props是異步請求回去的,那么他的第一次的值就為我們定義的初始值,沒定義就是undefined,等異步親貴回來之后,它早在第一次的時候,就把初始值賦值過了,請求回來后不再執行賦值了,所以就賦值不了返回后的結果,現已更改為使用watch來監聽props的改變,這里有個注意點:props綁定的父級屬性不能是返回結果后改變的屬性,比如說
···
<address @success="callback" :address="defaultVal">
//父級methods中
callback(val) {
this.defaultVal = val; //這樣是不對的, 因為你再子組件中watch了address相當於是defaultVal,如果你再callback中講子組件傳過來的值又賦值回去給defaultVal,就相當於又觸發了watch,
this.addressVal = val; //這樣才對。
}
