用户是在输入框输入值后模糊搜索某旅客表姓名
输入框需要在失焦后校验输入值的姓名格式
模拟用户点击模糊匹配的旅客姓名列表后
提示格式错误
项目 | Value |
---|---|
电脑 | M1 MBA2020 |
系统 | BigSur 11.6 |
node | 15.9 |
element-ui | 2.15.6 |
<template>
<div id="app">
<el-autocomplete v-model="test" :fetch-suggestions="querySearch" @select="handleSelect" @change="handleChange" >el-autocomplete>
div>
template>
export default {
data () {
return {
test: '',
restaurants: [{ "value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号" }]
}
},
methods: {
handleChange (val) {
alert(val)
},
handleSelect(item) {
console.log(item);
},
querySearch(queryString, cb) {
var restaurants = this.restaurants;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
// 调用 callback 返回建议列表的数据
cb(results);
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
}
}
}
code基本照搬 官网 el-autocomplete组件demo
找到el-autocomplete组件源码:node_modules/elementui-vue/node_modules/element-ui/packages/autocomplete/src/autocomplete.vue
查找触发chang事件代码
handleChange(value) {
this.$emit('change', value);
},
查找调用handleChange函数的代码
... other code
<el-input
ref="input"
v-bind="[$props, $attrs]"
@input="handleInput"
@change="handleChange"
@focus="handleFocus"
@blur="handleBlur"
@clear="handleClear"
@keydown.up.native.prevent="highlight(highlightedIndex - 1)"
@keydown.down.native.prevent="highlight(highlightedIndex + 1)"
@keydown.enter.native="handleKeyEnter"
@keydown.native.tab="close"
>
... other code
可以发现el-autocomplete组件直接监听子组件input的change事件并原封不动把值抛出来
当绑定了指令的组件被插入到dom时,修改组件的handleChange事件
注意:该方法仅适用于element-ui 2.13.2+版本,请看最终方案
<el-autocomplete v-get-selected-value ...>
el-autocomplete>
directives: {
'get-selected-value': {
inserted: function () {
const vnode = arguments[2].child
vnode.handleChange = val => {
if (vnode.$refs?.suggestions?.showPopper) {
const unwatch = vnode.$watch(() => vnode.$refs.suggestions.showPopper, function () {
unwatch()
vnode.$emit('change', val)
})
vnode.$once('select', item => {
unwatch()
vnode.$emit('change', item[vnode.valueKey])
})
} else {
vnode.$emit('change', val)
}
}
}
}
}
当我把自定义指令代码搬公司项目代码上发现,输入框每input一次就会执行修改的handleChange函数!T-T心累~~
当我再次确认demo的代码没问题后,发现两个项目的element-ui版本不一样。然后分别打开两个项目的autocomplete.vue源码进行对比,发现版本是2.13.0的代码中,handleChange函数直接绑定给input监听,这就解释通了。
<el-input
ref="input"
v-bind="[$props, $attrs]"
@input="handleChange"
...
>
补充文章:element-ui v2.13.2
Bug fixes
Autocomplete
Fix change event bug (#19200 by @sxzz)
不动你的handleChange函数,我直接给input子组件加个change事件监听,上代码!
directives: {
'get-selected-value': {
inserted: function () {
const vnode = arguments[2].child
// 弃用:vnode.handleChange = val => {
// 这里$off是为了移除高版本代码中新增的@change监听,否则直接加代码会有两个监听事件,触发两次change
vnode?.$refs?.input && vnode.$refs.input.$off('change').$on('change', val => {
if (vnode.$refs?.suggestions?.showPopper) {
const unwatch = vnode.$watch(() => vnode.$refs.suggestions.showPopper, function () {
unwatch()
vnode.$emit('change', val)
})
vnode.$once('select', item => {
unwatch()
vnode.$emit('change', item[vnode.valueKey])
})
} else {
vnode.$emit('change', val)
}
})
}
}
},
当然如果发现代码仍有BUG,欢迎指出