基于Vue实现多标签选择器
<html lang="en">
<head>
<title>Document</title>
<!-- 引入本地组件库 -->
<link rel="stylesheet" href="static/element-ui/">
<script src="static/element-ui/"></script>
<script src="static/element-ui/"></script>
<!-- 引入CDN样式 -->
<!-- <link rel="stylesheet" href="/element-ui/lib/theme-chalk/"> -->
<!-- <script src="/npm/vue/dist/"></script> -->
<!-- <script src="/element-ui/lib/"></script> -->
<style>
.not-active {
display: inline-block;
font-size: 12px;
margin: 5px 8px;
}
span {
margin: 0 2px;
}
</style>
</head>
<body>
<div id="app">
<!-- 待选标签 -->
<div v-for='(category, categoryIndex) in categories' :key="">
<!-- 分类 -->
<span class="not-active">{{}}:</span>
<template>
<span v-if=""class="not-active" @click="clearCategory(category, categoryIndex)"> 不限</span>
<my-tag v-else>不限</my-tag>
</template>
<!-- 标签 -->
<template v-for='(child, childIndex) in '>
<my-tag v-if="" :closable='true' @click-child='clickChild(category, categoryIndex, child, childIndex)'>
{{ }}
</my-tag>
<span v-else class="not-active" @click='clickChild(category, categoryIndex, child, childIndex)'>{{ }}</span>
</template>
</div>
<!-- 已选标签 -->
<div v-if=''>
<span class="not-active" @click="clearCondition">清空已选:<span>
<el-tag
v-for='(condition, index) in conditions'
:key=""
type="primary"
:closable="true"
size="small"
:disable-transitions="true"
@close='removeCondition(condition, index)'
@click='removeCondition(condition, index)'>
{{}}
</el-tag>
</div>
</div>
<script src="./"></script>
<script>
// 简单封装一个公用组件
Vue.component('my-tag', {
template: "<el-tag v-bind='$attrs' v-on='$listeners' effect='dark' size='small' :disable-transitions='true' @click='clickChild' @close='clickChild'><slot></slot></el-tag>",
methods: {
clickChild() {
this.$emit("click-child")
}
}
});
var app = new Vue({
el: '#app',
data() {
return {
categories, // 分类标签,可从外部加载配置
conditions: [] // 已选条件
}
},
watch: {
// 监听条件变化,按照请求接口拼装请求参数
conditions(val){
let selectedCondition = {};
for(let categorie of this.categories){
let selected_list = [];
for(let child of categorie.children){
if(child.active){
selected_list.push(child.name);
}
}
selectedCondition[categorie.name] = selected_list.join("|")
}
console.log(selectedCondition);
}
},
methods: {
// 处理标签点击事件,未选中则选中,已选中则取消选中
clickChild(category, categoryIndex, child, childIndex) {
let uid = `${categoryIndex}-${childIndex}`
child.uid = uid;
console.log(uid)
// 取消选择
if (child.active === true) {
category.count--;
child.active = false;
this.conditions.forEach((conditionChild, index) => {
if (conditionChild.uid === child.uid) {
this.conditions.splice(index, 1);
}
});
// 选择
} else {
category.count++;
child.active = true;
this.conditions.push(child);
}
},
// 清除已选整个类别标签
clearCategory(category, categoryIndex) {
category.count = 0;
// 可选列表均为未选中状态
category.children.forEach(child => {
child.active = false;
})
// 清空该类已选元素
for (let index = this.conditions.length - 1; index >= 0; index--) {
const conditionChild = this.conditions[index];
if (conditionChild.uid.startsWith(categoryIndex)) {
this.conditions.splice(index, 1);
}
}
},
// 移除一个条件
removeCondition(condition, index) {
let categoryIndex = condition.uid.split("-")[0];
this.categories[categoryIndex].count --;
this.conditions.splice(index, 1)
condition.active = false;
},
// 清空所有条件
clearCondition() {
for(let i = this.conditions.length-1; i >=0 ; i--){
this.removeCondition(this.conditions[i], i);
}
}
}
});
</script>
</body>
</html>