elementui解决el-select组件失去焦点blur事件每次获取的是上一次选值的问题
目录
↑↑↑↑↑↑↑↑↑↑↑↑ 不想看解决问题过程的可点击上方【封装自定义指令】目录直接跳转获取结果即可~~~
【问题描述】
一位朋友遇到这么一个开发场景:在表格里面嵌入el-select组件,每次修改值后,失去焦点时将修改值提交后台保存,但是发现在el-select组件失去焦点时,blur事件的evt.target.value值总为前一次选择的值;
【问题摘要】
1、el-select组件失去焦点时需要获取组件当前值而不是上一次的值;
2、el-select组件切换选项时不提交后台,只有当组件失去焦点后才提交当前值;
【分析问题】
一刚开始以为是下拉框收起动画延时问题导致内部value值被延时修改,所以就在blur事件里延时获取evt.target.value,貌似没问题了
-
blurHandler(evt){
-
setTimeout(() => {
-
console.log(evt.target.value);
-
},250)
-
},
随后又发现通过@blur绑定事件只会触发一次,好吧那就加修饰符吧:@blur.capture.native,好像解决只触发一次的问题了
-
<el-select v-model="value" @blur.capture.native="nativeBlurHandler" ref="select">
-
<el-option
-
v-for="item in options"
-
:key="item.value"
-
:label="item.label"
-
:value="item.value">
-
</el-option>
-
</el-select>
但是随之而来的问题就是,每次切换取值后都会触发一次blur事件,这可不是我们想要的,这不变成change事件了吗?继续深挖!
那就打印一下this.$refs.select看看吧,找到this.$refs.select.$data, 看里面有定义啥变量没,发现了如下变量:
-
log(eventName){
-
let {
-
createdSelected,
-
inputHovering,
-
isOnComposition,
-
isSilentBlur,
-
menuVisibleOnFocus,
-
softFocus,
-
visible
-
} = this.$refs.select.$data;
-
-
console.table([
-
{
-
name: eventName,
-
value: '',
-
},
-
// {
-
// name: 'createdSelected',
-
// value: createdSelected
-
// },
-
{
-
name: 'inputHovering',
-
value: inputHovering
-
},
-
// {
-
// name: 'isOnComposition',
-
// value: isOnComposition
-
// },
-
{
-
name: 'isSilentBlur',
-
value: isSilentBlur
-
},
-
// {
-
// name: 'menuVisibleOnFocus',
-
// value: menuVisibleOnFocus
-
// },
-
// {
-
// name: 'softFocus',
-
// value: softFocus
-
// },
-
{
-
name: 'visible',
-
value: visible
-
},
-
])
-
}
通过反复测试发现只有inputHovering,isSilentBlur,visible这三个变量与el-select组件的focus,blur事件有关联:
通过上图可以发现,只有最下方的失去焦点事件才是我们想要的,此时visible==false,isSilentBlur==true,正好满足我们的判断条件,于是blur事件改造成这样了:
-
nativeBlurHandler(evt){
-
console.log('nativeBlurHandler', {...this.$refs.select});
-
let {
-
isSilentBlur,
-
visible
-
} = this.$refs.select;
-
if( isSilentBlur && !visible ) {
-
console.log('提交', this.$refs.select.selected.currentValue);
-
}
-
this.log('blur事件');
-
},
又因为value取值从evt.target.value获取的不是实时的,也就是值不正确,继续深挖,发现this.$refs.select.selected.currentValue就是我们想要的正确的值,于是乎,问题就解决了!测试demo完整代码如下:
【完整Test代码】
-
-
<html>
-
<head>
-
<meta charset="UTF-8">
-
<!-- import CSS -->
-
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
-
</head>
-
<body>
-
<div id="app">
-
<el-select v-model="value" placeholder="请选择" @blur="blurHandler" @blur.capture.native="nativeBlurHandler" ref="select">
-
<el-option
-
v-for="item in options"
-
:key="item.value"
-
:label="item.label"
-
:value="item.value">
-
</el-option>
-
</el-select>
-
</div>
-
</body>
-
<!-- import Vue before Element -->
-
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
-
<!-- import JavaScript -->
-
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
-
<script>
-
let selectElm;
-
new Vue({
-
el: '#app',
-
data: function() {
-
return {
-
options: [{
-
value: '黄金糕',
-
label: '黄金糕'
-
}, {
-
value: '双皮奶',
-
label: '双皮奶'
-
}, {
-
value: '蚵仔煎',
-
label: '蚵仔煎'
-
}, {
-
value: '龙须面(传统面食)',
-
label: '龙须面(传统面食)'
-
}, {
-
value: '北京烤鸭',
-
label: '北京烤鸭'
-
}],
-
value: ''
-
}
-
},
-
methods: {
-
focusHandler(evt){
-
this.log('focus事件');
-
},
-
blurHandler(evt){
-
setTimeout(() => {
-
console.log(evt.target.value);
-
},250)
-
},
-
nativeBlurHandler(evt){
-
console.log('nativeBlurHandler', {...this.$refs.select});
-
let {
-
isSilentBlur,
-
visible
-
} = this.$refs.select;
-
if( isSilentBlur && !visible ) {
-
console.log('提交', this.$refs.select.selected.currentValue);
-
}
-
this.log('blur事件');
-
},
-
log(eventName){
-
let {
-
createdSelected,
-
inputHovering,
-
isOnComposition,
-
isSilentBlur,
-
menuVisibleOnFocus,
-
softFocus,
-
visible
-
} = this.$refs.select.$data;
-
-
console.table([
-
{
-
name: eventName,
-
value: '',
-
},
-
// {
-
// name: 'createdSelected',
-
// value: createdSelected
-
// },
-
{
-
name: 'inputHovering',
-
value: inputHovering
-
},
-
// {
-
// name: 'isOnComposition',
-
// value: isOnComposition
-
// },
-
{
-
name: 'isSilentBlur',
-
value: isSilentBlur
-
},
-
// {
-
// name: 'menuVisibleOnFocus',
-
// value: menuVisibleOnFocus
-
// },
-
// {
-
// name: 'softFocus',
-
// value: softFocus
-
// },
-
{
-
name: 'visible',
-
value: visible
-
},
-
])
-
}
-
}
-
})
-
</script>
-
</html>
【封装自定义指令】
想到给组件添加ref实际并不是那么好用且麻烦,所以我又将其封装成了指令,指令代码及用法如下,大家随取随用哈↓↓↓↓↓↓
-
-
<html>
-
<head>
-
<meta charset="UTF-8">
-
<!-- import CSS -->
-
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
-
</head>
-
<body>
-
<div id="app">
-
<el-row>
-
<el-col :span="24">
-
<el-select v-select-blur="selectBlurHandler" v-model="value">
-
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
-
</el-option>
-
</el-select>
-
</el-col>
-
</el-row>
-
</div>
-
</body>
-
<!-- import Vue before Element -->
-
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
-
<!-- import JavaScript -->
-
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
-
<script>
-
Vue.directive('select-blur', {
-
bind: function(el, binding, vnode) {
-
const selectComponent = vnode.componentInstance;
-
if( selectComponent.$options.name === 'ElSelect' ) {
-
selectComponent.$watch('visible', (n,o) => {
-
const {
-
isSilentBlur,
-
visible,
-
} = selectComponent;
-
if(isSilentBlur && !visible) {
-
selectComponent.handleBlur();
-
}
-
})
-
selectComponent.$on('blur', () => {
-
let {
-
visible,
-
selected: {
-
currentValue
-
}
-
} = selectComponent;
-
if (!visible) {
-
binding?.value && typeof binding.value === 'function' && binding.value(currentValue);
-
selectComponent.blur(); //处理页面频繁聚焦失焦导致重复触发blur事件的问题
-
}
-
}, true);
-
}
-
},
-
unbind: function(el, binding, vnode) {
-
const selectComponent = vnode.componentInstance;
-
if( selectComponent.$options.name === 'ElSelect' ) {
-
selectComponent.$off('blur');
-
}
-
}
-
});
-
-
const app = new Vue({
-
el: '#app',
-
data: function() {
-
return {
-
options: [{
-
value: '黄金糕',
-
label: '黄金糕'
-
}, {
-
value: '双皮奶',
-
label: '双皮奶'
-
}, {
-
value: '蚵仔煎',
-
label: '蚵仔煎'
-
}, {
-
value: '龙须面(传统面食)',
-
label: '龙须面(传统面食)'
-
}, {
-
value: '北京烤鸭',
-
label: '北京烤鸭'
-
}],
-
value: ''
-
}
-
},
-
methods: {
-
selectBlurHandler(val) {
-
console.log('提交', val);
-
},
-
}
-
})
-
</script>
-
</html>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggjjgb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13