最近使用element-ui開發時總有一個問題困擾著我。
當時要寫一個遠端搜尋選擇框元件, 這個元件關聯了一個後端的介面, 將後端返回的值對映到,繫結的物件上,
程式碼類似
<template>
<el-select remote :remote-method="getList" v-model="foo.name" key-value="name">
<el-option v-for="item in list" :value="item" :label="item.name"/>
</el-select>
</template>
<script>
export default {
data() {
return {
list: [],
foo: {
name: ``,
gender: ``,
email: ``,
...
}
}
},
methods: {
async getList(searchWord) {
const list = await get(searchWord)
// 返回的 list 的每一項的結構類似foo, 但有區別, 包含一些必要的資訊.
this.list = list
}
}
}
<script>
注意: 我將 option的value值繫結成了一個物件, 而 foo.name 本來是字串, 這樣的後果就是, 每次使用者點選選擇後 foo.name就會變為物件, 對後續的儲存造成了不方便,也破壞了原來的資料結構, 但如果不這麼做,又無法拿到使用者選擇項對應的所有的資料.這樣就造成了一個兩難的境地.
好在vue在文件中指出 v-model 實際就是vue封裝的語法糖.看這裡
<input v-model="bar">
相當於
<input :value="bar" @input="bar=arguments[0]">
所以我對程式做了如下的修改:
<template>
<el-select remote :remote-method="getList" :value="foo.name" @input="handleSelect(arguments[0])">
<el-option v-for="item in list" :value="item.name" :key="item.name" :label="item.name"/>
</el-select>
</template>
<script>
export default {
data() {
return {
list: [],
foo: {
name: ``,
gender: ``,
email: ``,
...
},
bar: null
}
},
methods: {
async getList(searchWord) {
const list = await get(searchWord)
this.list = list
},
handleSelect(val) {
this.foo.name = val.name
// 在input事件回撥中將使用者選中的物件賦值給一個準備好的變數
// 這樣就既可以拿到想要的物件又不會破壞 foo 物件原有的結構
this.bar = val
}
}
}
<script>
通過自定義 v-model 解決了一個常見到的小問題, 希望能給遇到相同問題的小夥伴一點幫助.