vue2 element-ui 中 el-radio 单选框点击事件失效问题

前情提要

点进这篇文章的小伙伴,应该和博主一样,都是遇到了这种单选框可点击取消的需求。也就只有这种不同寻常的需求,才能让我们发现element框架的缺陷点,话不多说,下面博主来提供一个解决思路。

@click为什么无法触发

其实很简单,在vue中有一条规则,@函数 在自定义组件上使用时,监听的是该组件内部触发的自定义事件方法,所以当我们对组件使用 @click 方法时,就需要组件在内部设置一个 $emit('click') 触发,我们观察下图el-redio 的源码,可以发现其未对 click 函数进行绑定

这也就是为什么 el-radioclick 事件无效,就是因为在el-radio 组件内部并未监听 click 方法,所以我们的事件失效了。而在 element-ui 组件中大部分组件都对 click 进行处理了,所以出现无法点击的问题,我们第一时间都是怀疑自己哪调错了。

使用 @click.native 触发方式解决

知道了原因,我们选择正确的方法就行,小伙伴们还记得在 vue 中出现的事件修饰符吗,其中一个 vue2 特有的修饰符 .native 刚好满足我们的要求,它的作用就是专门用于监听组件根元素的原生的事件

vue2特有修饰符 说明
.native 监听组件根元素的原生事件
.sync 双向绑定语法糖 (Vue 3 中已被 v-model 参数替代)

接着我们把代码中原本的 @click 改为 @click.native 并对元素进行一个判断,因为事件会向下捕获,我们进行一个元素名判断防止误触发,接着进行 setTimeout 延后处理,因为要取消功能必须保证click函数延后触发,不然会和单选框本身的选中逻辑有冲突,调整完成后我们可以尝试一下功能是否生效,

html 复制代码
<template>
	<el-radio v-model="select" :label="id" @click.native="select_Click($event,id)" />
</template>
<script>
	// methods 函数中
	select_Click(event, value) {
            // 处理点击元素
            if (event.target.tagName === 'INPUT') { return }
            const old = this.select // 记录一个过去值,防止判断出错
            setTimeout(() => {
                if (old === value) {
                  this.select = ''
                }
             }, 0)
      }
</script>

完整演示示例

html 复制代码
<template>
    <el-radio v-model="select" :label="id" @click.native="select_Click($event,id)" />
</template>
<script>
export default {
    data() {
        return {
        	id:1,
         	select:''
        }    
    },
    methods:{
        select_Click(event, value) {
            // 处理点击元素
            if (event.target.tagName === 'INPUT') { return }
            const old = this.select // 记录一个过去值,防止判断出错
            setTimeout(() => {
                if (old === value) {
                  this.select = ''
                  // 如果 el-radio 嵌套层级深可增加
                  // this.$forceUpdate()
                }
             }, 0)
        }    
    }
}
</script>
相关推荐
有来技术1 天前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东5161 天前
学院个人信息管理系统 (springboot+vue)
vue.js·spring boot·后端·个人开发·毕设
m0_748229991 天前
Vue2 vs Vue3:核心差异全解析
前端·javascript·vue.js
德育处主任Pro1 天前
『NAS』在群晖部署一款太空策略游戏-ogame-vue-ts
前端·vue.js·游戏
css趣多多1 天前
render函数
前端·javascript·vue.js
web打印社区1 天前
前端开发实现PDF打印需求:从基础方案到专业解决方案
前端·vue.js·react.js·electron·pdf
Trae1ounG1 天前
Vue Iframe
前端·javascript·vue.js
爱上妖精的尾巴1 天前
8-1 WPS JS宏 String.raw等关于字符串的3种引用方式
前端·javascript·vue.js·wps·js宏·jsa
web打印社区1 天前
vue页面打印:printjs实现与进阶方案推荐
前端·javascript·vue.js·electron·html
daols881 天前
vue2 甘特图 vxe-gantt 一行渲染多个子任务的配置
vue.js·甘特图·vxe-table