【elementui】解决el-select组件失去焦点blur事件每次获取的是上一次选中值的问题

news2025/1/19 11:24:07

目录

【问题描述】

【问题摘要】 

【分析问题】

 【完整Test代码】

【封装自定义指令】


↑↑↑↑↑↑↑↑↑↑↑↑ 不想看解决问题过程的可点击上方【封装自定义指令】目录直接跳转获取结果即可~~~

 

【问题描述】

        一位朋友遇到这么一个开发场景:在表格里面嵌入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代码】

<!DOCTYPE html>
<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实际并不是那么好用且麻烦,所以我又将其封装成了指令,指令代码及用法如下,大家随取随用哈↓↓↓↓↓↓

<!DOCTYPE html>
<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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/829065.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Packet Tracer - 配置初始交换机设置

Packet Tracer - 配置初始交换机设置 拓扑 目标 第 1 部分&#xff1a;检验默认交换机配置 第 2 部分&#xff1a;配置基本交换机配置 第 3 部分&#xff1a;配置 MOTD 标语 第 4 部分&#xff1a;将配置文件保存到 NVRAM 第 5 部分&#xff1a;配置 S2 拓扑图 背景信息…

【Mybatis】XML映射文件

目录 11.3XML映射文件 1.select 2.insert、update、delete 3.Sql 4.parameters(参数) 5.resultMap 6.resultMap 使用示例 (1)在先前创建的数据库stu中创建表student 2&#xff0c;并插入若干条数据&#xff0c;代码如下&#xff1a; (2)创建工程mybatis_ResultMap_demo。 (…

Qt项目---简单的计算器

在这篇技术博客中&#xff0c;我们将介绍如何使用Qt框架实现一个简单的计算器应用。我们将使用C编程语言和Qt的图形用户界面库来开发这个应用&#xff0c;并展示如何实现基本的算术操作。 项目设置 首先&#xff0c;我们需要在Qt Creator中创建一个新的Qt Widgets应用程序项目…

7.物联网操作系统互斥信号量

优先级翻转问题 优先级翻转功能需求 优先级翻转功能实现 一。实验&#xff1a;优先级翻转问题 1.优先级翻转的解释 &#xff08;1&#xff09;有三个任务&#xff0c;一个任务L优先级最低&#xff0c;一个任务M优先级为中间&#xff0c;一个任务H优先级为最高。 &#xff08…

SpringBoot集成企业微信群聊机器人消息

目录 参考文档概述一、功能作用二、应用场景三、 群机器人发送限制四、创建机器人1、添加2、群机器人Webhook地址 五、发送消息1、文本 text请求体 图文连接 news 参考文档 官方文档 企业微信群机器人应用 概述 现在很多企业都在使用企业微信进行工作交流&#xff0c;自从企…

静态路由下一跳地址怎么确定(静态路由配置及讲解)

一、用到的所有命令及功能 ①ip route-static 到达网络地址 子网掩码 下一跳 // 配置静态路由下一跳指的是和当前网络直接连接的路由器的接口地址非直连网段必须全部做路由路径是手工指定的&#xff0c;在大规模网络上不能用&#xff0c;效率低&#xff0c;路径是固定的稳定的…

寻找旋转排序数组中的最小值——力扣153

文章目录 题目描述解法 二分法 题目描述 解法 二分法 int findMin(vector<int>& nums){int l0, rnums.size()-1;while(l<r){int mid (lr)/2;if(nums[mid]<nums[r]) rmid;else lmid1;}return nums[l];}

基于freeRTOS的垃圾桶(cubeMX)

前言&#xff1a;最近学习了freertos的任务、队列、互斥量、任务标志位等理论知识&#xff0c;看着都会就怕一练就废&#xff0c;于是打算做些项目巩固一下&#xff0c;加深一下对freertos知识的理解。 一、项目介绍 项目简单需求&#xff1a; 检测靠近时&#xff0c;垃圾桶自…

APUE学习62章终端(二): stty命令特殊字符终端标志

1. stty命令 stty命令的英文解释: 很明显stty有一个-F参数 所以准确的说: stty命令是设置当前终端驱动程序(也有可能直接配置了硬件&#xff0c;这点目前不清楚)的属性&#xff0c;使当前终端的驱动程序能够使能/去使能一些特殊字符的识别与处理等等 2. stty命令的结构 3. 终端…

Python web实战之 Django 的 ORM 框架详解

本文关键词&#xff1a;Python、Django、ORM。 概要 在 Python Web 开发中&#xff0c;ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;是一个非常重要的概念。ORM 框架可以让我们不用编写 SQL 语句&#xff0c;就能够使用对象的方式来操作数据…

总结946

6:40起床 7&#xff1a;15~8:00早读&#xff0c;07年tex1,2 8:10~10:12 880第二章选填&#xff0c;题目有些综合&#xff0c;错的有些多呀&#xff0c;不要紧&#xff0c;拿下它&#xff0c;就有进步了。 10:28~11:27重做强化18讲6道题 12&#xff1a;10~2:15吃饭睡觉&…

MySQL 三大日志日志:undo log、redo log、binlog

目录 一条SQL的执行流程 为什么需要 undo log&#xff1f; undo log 是如何刷盘&#xff08;持久化到磁盘&#xff09;的&#xff1f; 为什么需要 Buffer Pool&#xff1f; Buffer Pool 缓存什么&#xff1f; Undo 页是记录什么&#xff1f; 查询一条记录&#xff0c;就只需…

代码随想录算法训练营第三十二天 | Leetcode随机抽题检测

Leetcode随机抽题检测 46 全排列未看解答自己编写的青春版重点题解的代码日后复习重新编写 78 子集未看解答自己编写的青春版重点题解的代码日后复习重新编写 17 电话号码的字母组合未看解答自己编写的青春版重点题解的代码日后复习重新编写 39 组合总和未看解答自己编写的青春…

SpringBoot项目增加logback日志文件

一、简介 在开发和调试过程中&#xff0c;日志是一项非常重要的工具。它不仅可以帮助我们快速定位和解决问题&#xff0c;还可以记录和监控系统的运行状态。Spring Boot默认提供了一套简单易用且功能强大的日志框架logback&#xff0c;本文将介绍如何在Spring Boot项目中配置和…

使用AIGC工具提升安全工作效率

新钛云服已累计为您分享760篇技术干货 在日常工作中&#xff0c;安全人员可能会涉及各种各样的安全任务&#xff0c;包括但不限于&#xff1a; 开发某些安全工具的插件&#xff0c;满足自己特定的安全需求&#xff1b;自定义github搜索工具&#xff0c;快速查找所需的安全资料、…

HTML基础介绍2

表单格式化 ctrld&#xff1a;复制选中行数的所有代码 ctrlx&#xff1a;删除代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>表单综合案例</title> </head> <body> <!--…

(AcWing)01背包问题

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 ii 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数N&#xff0c;V&…

0基础学习VR全景平台篇 第76篇:全景相机-圆周率全景相机如何直播推流

圆周率科技&#xff0c;成立于2012年&#xff0c;是中国最早投身嵌入式全景算法研发的团队之一&#xff0c;亦是全球市场占有率最大的全景算法供应商。相继推出一体化智能屏、支持一键高清全景直播的智慧全景相机--Pilot Era和Pilot One&#xff0c;为用户带来实时畅享8K的高清…

【AGI】世界首次实现室温超导LK-99

论文&#xff1a;The First Room-Temperature Ambient-Pressure Superconductor GPT论文总结&#xff1a; 根据所提供的信息&#xff0c;这篇论文报道了一种在室温和常压下工作的室温超导体LK-99。LK-99的超导性是通过微小的结构畸变引起的&#xff0c;而不是通过温度和压力等外…

快速部署外卖系统:利用现代工具简化开发流程

在竞争激烈的外卖市场中&#xff0c;快速部署高效稳定的外卖系统是餐饮企业成功的关键之一。本文将介绍如何利用现代工具简化外卖系统的开发流程&#xff0c;并附带代码示例&#xff0c;帮助开发者快速搭建功能完备、用户友好的外卖平台。 1. 简介 在外卖业务快速增长的背景…