最近使用element-ui开发时总有一个问题困扰着我。
当时要写一个远程搜索选择框组件, 这个组件关联了一个后端的接口, 将后端返回的值映射到,绑定的对象上,
代码相似html
<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封装的语法糖.看这里vue
<input v-model="bar">
至关于element-ui
<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 解决了一个常见到的小问题, 但愿能给遇到相同问题的小伙伴一点帮助.数据结构