基于iview组件实现标签选择器单选功能(可点击取消)

功能需求:需要若干选项按钮,选中后将相应的内容显现出来,单选,第一次点击选中,再次点击取消选中。

解决思路:使用iview RadioGroup组件可满足点击选中、单选的功能,其余功能再进行改造
在这里插入图片描述

<RadioGroup v-model="RadioGroupData" type="button" class="recommandStyle" size="small">
      <Radio 
        :class="{'cancelSelect':cancelSelect[0]}" 
        @click.native="changeRecommandData('岗位+地区')"
        label="岗位+地区"
      ></Radio>
      <Radio 
        :class="{'cancelSelect':cancelSelect[1]}" 
        @click.native="changeRecommandData('岗位+性别+地区')" 
        label="岗位+性别+地区"
      ></Radio>
      <Radio 
        :class="{'cancelSelect':cancelSelect[2]}" 
        @click.native="changeRecommandData('岗位+年龄+地区')" 
        label="岗位+年龄+地区"
       ></Radio>
      <Radio 
        :class="{'cancelSelect':cancelSelect[3]}" 
        @click.native="changeRecommandData('岗位+性别+年龄')" 
        label="岗位+性别+年龄"
      ></Radio>
      <Radio 
        :class="{'cancelSelect':cancelSelect[4]}"
        @click.native="changeRecommandData('岗位+性别+年龄+地区+行业')" 
        label="岗位+性别+年龄+地区+行业"
      ></Radio>
</RadioGroup>
data: {
    cancelSelect: [false, false, false, false, false],
    evTimeStamp: 0,
    currentIndex: null,
}

cancelSelect 数组的长度为按钮的数量,作用是控制相应按钮的样式。
给每个Radio项注册点击事件(不能注册change事件,否则再次点击on-change事件会没有相应,不能满足再次点击取消选中的需求),
但注册好点击事件点击时会响应两次点击函数(原因:点击label的时候,事件冒泡一次,同时触发关联的input的点击事件,导致事件再次冒泡)
解决方法:1、根据事件触发的时间戳来判断,相隔太近则认为是一次点击
2、响应函数里判断event的tagName,如果tagName为label则不做处理。这个方法的问题就是要做event的浏览器兼容,还要判断label有没有关联input等,较复杂,不考虑

// 匹配项切换
      changeRecommandData(e) {
        let now = +new Date();
        if (now - this.evTimeStamp < 100) {
            return;
        }
        this.evTimeStamp = now;
        switch(e) {
          case "岗位+地区":
            this.recommandData = this.recommandData != e ? e : ''
            this.searchList = this.recommandData ? ['job', 'workPlace'] : ['job']
            this.cancelSelect[0] = this.recommandData ? false : true
            this.currentIndex = this.recommandData ? 0 : null
            break;
          case "岗位+性别+地区":
            this.recommandData = this.recommandData != e ? e : ''
            this.searchList = this.recommandData ? ['job', 'workPlace', 'sex'] : ['job']
            this.cancelSelect[1] = this.recommandData ? false : true
            this.currentIndex = this.recommandData ? 1 : null
            break;
          case "岗位+年龄+地区":
            this.recommandData = this.recommandData != e ? e : ''
            this.searchList = this.recommandData ? ['job', 'workPlace', 'age'] : ['job']
            this.cancelSelect[2] = this.recommandData ? false : true
            this.currentIndex = this.recommandData ? 2 : null
            break;
          case "岗位+性别+年龄":
            this.recommandData = this.recommandData != e ? e : ''
            this.searchList = this.recommandData ? ['job', 'sex', 'age'] : ['job']
            this.cancelSelect[3] = this.recommandData ? false : true
            this.currentIndex = this.recommandData ? 3 : null
            break;
          case "岗位+性别+年龄+地区+行业":
            this.recommandData = this.recommandData != e ? e : ''
            this.searchList = this.recommandData ? ['job', 'workPlace', 'sex', 'age', 'industry'] : ['job']
            this.cancelSelect[4] = this.recommandData ? false : true
            this.currentIndex = this.recommandData ? 4 : null
            break;
        }
      },

     // 清空搜索条件
      clearSearch() {
        this.searchList = ['job'];
        this.recommandData = '';
        if(this.currentIndex != null) {
          this.cancelSelect[this.currentIndex] = true;
        }
        this.searchData.jobId = '';
        this.projectId = '';
      },
<style lang=‘less’>
  .recommandStyle {
    .ivu-radio-wrapper.ivu-radio-group-item {
      font-size: 12px;
      background-color: #ededed;
      margin-right: 10px;
      border-radius: 0 !important;
      box-shadow: none !important;
      border: 1px solid #d7dde4;
    }
    .cancelSelect {
      color: #606266 !important;
      border-color: #d7dde4 !important;
    }
  }
</style>
封装成组件:

父组件

<template>
    <div>
        <tagSelect :dataList="dataList"></tagSelect>
    </div>
</template>
<script>
import tagSelect from '@tagSelect.vue'
export default {
  data () {
   return {
       dataList: [],
   }
  },
  components: {
      tagSelect
  },
  mounted(){
      this.setDataList();
  },
  methods: {
      setDataList() {
          this.dataList = [
              {value: '岗位+地区', lable: '岗位+地区'},
              {value: '岗位+性别+地区', lable: '岗位+性别+地区'},
              {value: '岗位+年龄+地区', lable: '岗位+年龄+地区'},
              {value: '岗位+性别+年龄', lable: '岗位+性别+年龄'},
              {value: '岗位+性别+年龄+地区+行业', lable: '岗位+性别+年龄+地区+行业'}
          ]
      }
  }
}
</script>
<style>
 
</style>

子组件

<template>
    <div>
        <RadioGroup v-model="RadioGroupData" type="button" class="recommandStyle" size="small">
            <Radio
                v-for="(item, index) in dataList"
                :key="index"
                @click.native="changeRecommandData(item.label)"
                :class="{'cancelSelect':cancelSelect[index]}"
                :label="item.label"
            ></Radio>
        </RadioGroup>
    </div>
</template>
<script>
 export default {
   name: 'tagSelect',
   props : ['dataList'],
   data () {
    return {
        evTimeStamp: 0,
        recommandData: '',
        searchList: [],
        currentIndex: null,
        cancelSelect: []
    }
   },
   components: {
   },
   created() {
       this.dataList.forEach((item, index) => {
            this.$set(this.cancelSelect, index, false)
       })
   },
   methods: {
       changeRecommandData(e) {
           let now = +new Date();
           if (now - this.evTimeStamp < 100) {
               return;
           }
           this.evTimeStamp = now;
           this.dataList.forEach((item, index) => {
               if(e == item.label) {
                    this.recommandData = this.recommandData != e ? e : ''
                    this.cancelSelect[index] = this.recommandData ? false : true
                    this.$set(this.cancelSelect, index, this.recommandData ? false : true)
                    this.currentIndex = this.recommandData ? 0 : null
                    console.log(this.cancelSelect[index])
               } else {
                   this.$set(this.cancelSelect, index, false)
               }
           })
       }
   }
 }
</script>
<style lang="less">
.recommandStyle {
    .ivu-radio-wrapper.ivu-radio-group-item {
        font-size: 12px;
        background-color: #ededed;
        margin-right: 10px;
        border-radius: 0 !important;
        box-shadow: none !important;
        border: 1px solid #d7dde4;
    }
    .cancelSelect {
        color: #606266 !important;
        border-color: #d7dde4 !important;
    }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值