功能需求:需要若干选项按钮,选中后将相应的内容显现出来,单选,第一次点击选中,再次点击取消选中。
解决思路:使用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>