效果演示:
一、组件:
组件内部实现支持多选、单选能力;多选情况支持全选、反选、清空。
思路:
1、数据:
selectedArr 存储当前选中的数据。
单选:如果selectedArr[0] 等于当前选择数据,清空selectedArr ,否则赋值给 selectedArr[0] 。数组长度为0或1
多选:当前选择数据不在selectedArr 中,则push,否则splice。
2、样式:动态绑定样式,数组selectedArr中含有当前元素,则添加选中样式。
组件完整代码:
<template>
<div class="cmp-container">
<div v-if="data.length>0">
<!--支持多选-->
<div class="btn-wrapper" v-if="type ==='multiple'">
<span class="title-text" @click="selectedAll()">
全选
</span
>
<span class="title-text" @click="toggle()">
反选
</span>
<span class="title-text" @click="cancelSelect()">
清空
</span>
</div>
<div class="grid">
<span v-for="(item,index) in data"
:key="index"
class="grid-item"
@click="select(index)"
:class="{'span-active':selectedArr.indexOf(index) !==-1}"
>
{{ item.text }}
</span>
</div>
</div>
<div v-else>
<span> 暂无数据 </span>
</div>
</div>
</template>
<script>
export default {
components: {},
props: {
data: {
type: Array,
default: () => {
return [];
}
},
selected: {
type: Array,
default: () => {
return [];
}
},
type: {
type: String,
default: "single" //single单选 multiple 多选
}
},
data() {
return {
selectedArr: []
};
},
watch: {
selectedArr: {
handler(val) {
let arr = [];
let textArr =[];
val.forEach((el) => {
arr.push(this.data[el].value);
textArr.push(this.data[el].text);
});
this.$emit("update", arr,textArr);
},
deep: true
}
},
computed: {},
mounted() {
},
methods: {
select(index) {
if (this.type === "single") {//单选
if (this.selectedArr[0] !== index) {
this.selectedArr = [];
this.selectedArr.push(index);
} else {
this.selectedArr = [];
}
} else { //可多选
let searchIndex = this.selectedArr.indexOf(index);
if (searchIndex === -1) {
this.selectedArr.push(index);
} else {
this.selectedArr.splice(searchIndex, 1);
}
}
},
/**
* 全选
*/
selectedAll() {
this.selectedArr = Array(this.data.length).fill(null).map((_, index) => index);
},
/**
* 反选
*/
toggle() {
let arr = Array(this.data.length).fill(null).map((_, index) => index);
this.selectedArr = arr.filter((_item, _index, _arr) => {
return this.selectedArr.indexOf(_item) === -1;
});
},
/**
* 清空选择
*/
cancelSelect() {
this.selectedArr = [];
}
}
};
</script>
<style lang="less" scoped>
@import url("~@/assets/style/common.less");
.cmp-container {
background: white;
}
.btn-wrapper {
padding-top: 10px;
}
.select-btn {
color: blueviolet;
font-size: 14px;
padding: 10px;
}
.grid {
display: flex;
flex-wrap: wrap;
padding: 10px;
}
.grid-item {
margin: 8px 4px;
padding: 10px 5px;
border-radius: 16px;
display: block;
text-align: center;
box-sizing: border-box;
width: 30%;
font-size: 10px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
background: rgba(0, 0, 0, 0.05);
cursor: pointer;
}
.span-active {
color: white;
background: rgba(138, 43, 226, 0.7);
}
.title-text{
color: #576b95;
padding: 5px;
cursor: pointer;
}
</style>
二、页面中引用:
完整代码:
<template>
<div class="selected-paged">
<div style="width: 400px">
<span class="selected-text">当前选中:</span>
<span class="selected-content">{{ singleSelected }}</span>
<label-selector :data="selectList" type="single" @update="updateSingle"></label-selector>
</div>
<div style="margin-top: 40px;width: 400px">
<span class="selected-text">当前选中:</span>
<span class="selected-content">{{ multipleSelected }}</span>
<label-selector :data="selectList" type="multiple" @update="updateMultiple"></label-selector>
</div>
</div>
</template>
<script>
import LabelSelector from "@/components/LabelSelector";
export default {
name: "",
components: {
LabelSelector
},
data() {
return {
selectList: [
{ text: "飞机", value: "01" },
{ text: "火车", value: "02" },
{ text: "大巴", value: "03" },
{ text: "高铁", value: "04" },
{ text: "出租车", value: "05" },
{ text: "自行车", value: "05" },
{ text: "火箭", value: "07" },
{ text: "潜艇", value: "08" },
{ text: "航空母舰", value: "08" },
{ text: "游轮", value: "09" }
],
singleSelected: "",
multipleSelected: ""
};
},
created() {
},
mounted() {
},
methods: {
updateSingle(valueArr,textArr) {
this.singleSelected = textArr.toString();
},
updateMultiple(valueArr,textArr) {
this.multipleSelected = textArr.toString();
}
}
};
</script>
<style lang='less' scoped>
.selected-text {
font-size: 16px;
}
.selected-content{
display: block;
height: 30px;
}
</style>
总结:
每天记录一点,从小小菜鸟变小菜鸟!!!
版权声明:本文为King0217原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。