element-ui中el-radio组件绑定点击事件触发两次的解决办法

一. 需求:

今天在做项目时有这样一个需求,需要做个单选框,然后点击选中,再次点击时取消,如下图:

在这里插入图片描述
我用的是element-ui的el-radio,代码如下:

<el-row type="flex">
  <el-col :span="24">
    <el-radio v-model="radioCode" @click.native="isSendMessage" :label="true">是否将此原因同步短信发送给用户</el-radio>
  </el-col>
</el-row>

export default {
  data() {
    radioCode: false
  },
  methods: {
    isSendMessage() {
      this.radioCode = !this.radioCode
    }
  }
}

写好以上代码以后,默认界面如下图

在这里插入图片描述
点击一次以及n次以后都是选中的状态,如下图

在这里插入图片描述
发现不对以后,我就在上面的methods里面加了打印看看

 methods: {
   isSendMessage() {
     console.log('我被触发啦')
     this.radioCode = !this.radioCode
   }
 }

运行结果如下:

在这里插入图片描述
发现点击事件被触发了两次

二. 问题原因

1.element-ui中,el-radio组件包含了label和input标签,在el-radio上设置了点击事件,让两个标签都拥有了该事件。

三. 解决办法

第一种方法:

因为是同时触发了input标签和label标签的点击事件,就可以通过$event拿到对应事件的标签元素,通过加判断阻止其中一个就可以了。代码如下:

<el-row type="flex">
  <el-col :span="24">
    <el-radio v-model="radioCode" @click.native="isSendMessage($event)" :label="true">是否将此原因同步短信发送给用户</el-radio>
  </el-col>
</el-row>

export default {
  data() {
    radioCode: false
  },
  methods: {
    isSendMessage(el) {
      // console.log(el)
      // 当是input标签触发的点击事件时,阻止该事件
      if (el.target.tagName === 'INPUT') return 
      this.radioCode = !this.radioCode
    }
  }
}

效果如下:

点击一次

在这里插入图片描述
再次点击

在这里插入图片描述
成功实现了功能

第二种方法:

考虑可能是事件冒泡的原因导致触发两次点击事件,我又加了.stop修饰符

<el-radio v-model="radioCode" @click.native.stop="isSendMessage($event)" :label="true">

然而发现并没有效果,改为.prevent修饰符阻止默认事件才有效果

<el-row type="flex">
  <el-col :span="24">
    <el-radio v-model="radioCode" @click.native.prevent="isSendMessage" :label="true">是否将此原因同步短信发送给用户</el-radio>
  </el-col>
</el-row>

export default {
  data() {
    radioCode: false
  },
  methods: {
    isSendMessage() {
      this.radioCode = !this.radioCode
    }
  }
}

点击选中如下

在这里插入图片描述
点击取消选中如下

在这里插入图片描述
该方法也可以实现功能,但是为什么点击取消以后,会有蓝色的光圈,而不是默认状态的灰色呢?

在这里插入图片描述

四. 突然事件

我突然想到一个问题,默认是未选中状态,触发两次事件,变量值应该是恢复原值,也就是单选框应该还是未选中状态,但是为什么一直保持选中状态了呢?伤脑壳儿~

于是在未解决问题的代码中,我打印了我设置的变量看看值是怎么变化的,代码如下:

methods: {
  isSendMessage(el) {
    console.log('我被触发啦')
    this.radioCode = !this.radioCode
    console.log(this.radioCode)
  }
}

点击3次单选框以后的打印结果如下图:

在这里插入图片描述
惊奇的发现,第一次点击以后本来最后打印的结果是false,和label的值不一样,应该是未选中状态,然后此时却是已选中状态。并且也可以从第二次点击以后的打印看来,在第二次点击前this.radio的值已经变为true了。

难道是el-radio源码里面改了this.radio的值吗。但是在改了一次之后就没再改了,后面就一直保持选中状态。也就是this.radio在第二次点击前被改为true,经历了两次点击以后还是true,就这样一直持续下去了。

脑壳儿痛~想了一下,有可能是我只有一个单选框选项且没设置默认值的原因。有空再好好研究下源码看看是怎么回事,再来补充修改。

但是~但是不甘心的我又做了如下操作:

<el-row type="flex">
  <el-col :span="24">
    <el-radio v-model="radioCode" @click.native="isSendMessage" :label="true">是否将此原因同步短信发送给用户</el-radio>
  </el-col>
</el-row>

export default {
  data() {
    radioCode: false,
    num: 0
  },
  methods: {
    isSendMessage() {
      let num = 0
      this.num++
      if(this.num % 2) {
        this.radioCode = true
      }else {
        this.radioCode = false
      }
    }
  }
}

突然发现,该方法不用加任何修饰符或者通过$event阻止其中一个事件,都能实现功能,脑壳儿再次的痛了~

文末

后面彻底搞明白了,再来补充修改。。。

有说错的地方,还望大佬兄台能够指出来,谢谢啦

讨论数量: 0

慎思笃行