• 给饿了么Radio 单选框添加点击事件


    前言

    在这里插入图片描述
    最近有一个这样的需求,当点击不合格时打开一个弹窗进行不合格数据的录入。问题点在于当你想对不合格数据进行修改时,点击不合格是没有反应的;因为Radio 单选框只提供了一个change 事件

    解决

    这里说明一下,项目是vue2的项目,写这个demo是vue3的项目。但是两者的情况有些不一样。

    问题1

    vue2

    <el-radio-group v-model="result">
      <el-radio :label="0" @click.native="radioClick">不合格</el-radio>
      <el-radio :label="1">合格</el-radio>
    </el-radio-group>
    
    • 1
    • 2
    • 3
    • 4

    vue3

    <el-radio-group v-model="result">
      <el-radio :label="0" @click="radioClick">不合格</el-radio>
      <el-radio :label="1">合格</el-radio>
    </el-radio-group>
    
    • 1
    • 2
    • 3
    • 4

    在这里也发现了我的一个误解,@click 本质是一个自定义事件,只是与原生的点击事件功能上是一致的。
    在vue2中有这样一句话
    在这里插入图片描述
    所以在vue2中直接@click是不生效的,因为Radio 单选框没有提供这样的事件;但是加上.native修饰符后这就是原生事件了,因此点击事件会生效。

    vue3中直接使用@click生效是因为vue3中移除了.native修饰符,@click默认就是原生的点击事件

    问题2

    点击事件解决了,但是该事件每次都会被触发两次。原因是因为el-radio被封装了好几层,根元素不是input,解决是在后面添加prevent

    //vue2
     <el-radio :label="0" @click.native.prevent="radioClick">不合格</el-radio> 
    //vue3
     <el-radio :label="0" @click.prevent="radioClick">不合格</el-radio>
    
    • 1
    • 2
    • 3
    • 4

    至于为什么使用prevent可以解决这个问题,暂时没有找到原因

    问题3

    点击问题解决了,触发两次解决了,但是加上prevent后,单选框是无法被选中的。
    解决:手动进行赋值

    const radioClick = () => {
        result.value = 0;
        console.log('点击了', result.value);
    };
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    最终方案

    看上面的动图其实可以看到还是有点小问题的,手动赋值后选中状态多了一圈,要在旁边空白地方点击一下才能变成正常的选中状态。如果不介意的话,这样就可以了,比较很简单。

    还有一种解决方案,指令(yyds)

    vue2

      directives: {
          radioClick: {
              bind(el,binding) {
                  //  console.log(el);
                  console.log(el.getElementsByClassName('el-radio__original')[0].getAttribute('value'));
                  if(el.getElementsByClassName('el-radio__original')[0].getAttribute('value') == 2) {
                      el.getElementsByClassName('el-radio__original')[0].addEventListener('click',() => {
                          console.log('点击了',binding.value);
                      });
                  }
              }
          }
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    vue3

    const vRadioClick = {
        mounted: (el, binding) => {
            if (el.getElementsByClassName('el-radio__original')[0].getAttribute('value') == 0) {
                el.getElementsByClassName('el-radio__original')[0].addEventListener('click', () => {
                    console.log('点击了', binding.value);
                });
            }
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    补充

    本来以为上面就解决了,原来小丑竟然是自己。在指令中是无法获取到this 的,查了下需要借助指令的第三个参数

    在这里插入图片描述
    vnode.context 就是我们需要的 this

  • 相关阅读:
    93. 复原 IP 地址(力扣LeetCode)
    正点原子stm32F407学习笔记5——串口通信实验
    643. 子数组最大平均数I(滑动窗口)
    【深度学习】SimSwap: An Efficient Framework For High Fidelity Face Swapping 换脸,实战
    字节码进阶之JVM Attach API详解
    【java】基本数据类型、包装类、string之间的转换
    STM32--PWR电源控制
    pyflink 设置流批模式
    Redis类型
    Flink原理与实现:数据交换策略
  • 原文地址:https://blog.csdn.net/weixin_41897680/article/details/126671286