近來做一個簡單自動發卡小系統,兩個下拉選擇框。第一個框為分類,選擇分類后,第二個框按分類id在線請求顯示分類下面的商品供選擇。這是一個很簡單的需求。
但發現第二個框不能正常選擇,表現為選了不改變。經測試,其實select的值已經變了,但顯示沒變。
相關代碼如下:
el-select綁定了form下的goods_name屬性,選項綁定了根屬性goods:
<el-select v-model="form.goods_name" placeholder="選擇商品" size="mini" @change="goods_change"> <el-option v-for="item in goods" :key="item._id" :label="item.name" :value="item.name"> </el-option> </el-select>
data中的form:
data() { return { activeName: 'all', form:{}, types:[], goods:[], kami_s:'', placeholder:'一行一條\ngoogle' }; },
分類改變后請求商品的操作:
async type_change(type){ const d = await this.$http.post('/goods/api/get_goods',{type_id:type}) if(d.data.data.length > 0){ let a = d.data.data.filter(el=>{ return el.active === 1 }) a.sort((e1,e2)=>{ return e1.sort - e2.sort }) this.goods = a this.form.goods_name = '' }
this.form.goods_name = ''這個操作,不能將select清空,選擇不同分類后商品名稱下拉選擇變了,但選了之后不顯示。但console.log出來看其實goods_name的值是選擇之后的。
搜索了很多,問題在vue的響應式上,vue文檔中有說明:

因為select綁定的是form中的goods_name,goods_name最初是沒有定義在form中的,所以goods_name不是響應式的。
同樣,選擇項goods是最初定義好的根級別屬性,是響應式的,所以分類改變后,商品下拉選擇會改變。
知道了原因,就好解決了。網上有一種,給select綁定一個change事件,如:
@change="goods_change",然后在goods_change中強制渲染的方式,我沒有成功,而且vue也強烈不推薦這樣做:
goods_change(){ this.$foreUpdate() }
解決方式一:直接在form中定義一個goods_name,這樣goods_name就成了響應式:
data() { return { activeName: 'all', form:{goods_name:''}, types:[], goods:[], kami_s:'', placeholder:'一行一條\ngoogle' } }, //然后重置select也沒問題,選擇也沒問題 this.form.goods_name = this.goods[0].name //或 this.form.goods_name = ''
解決方式二:不在form中定義goods_name,使用this.$set()來顯式更新對象的屬性:
//在請求商品后的事件中,重置select的值 : this.$set(this.form,'goods_name','') //這樣是不行的,不是響應式: this.form.good_name = ''
這是vue的基礎,真正遇到時一時半會想不到,到處搜索,還以為是element的BUG。記錄一下。