一. 需求:

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

在这里插入图片描述
我用的是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次单选框以后的打印结果如下图:(this.radioCode默认值是false,触发两次理论上的变化应该是false — true — false)

在这里插入图片描述
惊奇的发现,第一次点击以后本来最后打印的结果是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阻止其中一个事件,都能实现功能,脑壳儿再次的痛了~

五. 文末

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

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

GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:1 个月前 )
c345bb45 5 个月前
a07f3a59 * Update transition.md * Update table.md * Update transition.md * Update table.md * Update transition.md * Update table.md * Update table.md * Update transition.md * Update popover.md 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐