最近的项目中使用筛选写的比较多,每次都要做一些修改才能用到项目上,而且还要看一看代码才能改动。这次又用到,就顺便写成不依赖其他UI框架,下次使用时方便直接引用,再也不想造轮子了!👀
先出效果
组件代码
<template>
<div class="filter-box">
<div class="filter flex-row">
<p v-for="(v, k) in data" :key="k" :class="filterIndex==k? 'active':''" @click="itemClicked(k)">{{v.name}}</p>
</div>
<div class="filter-overlay" :class="filterShow? 'active':''" @click="filterShow=false; filterIndex='-1'">
<div v-if="filterShow" class="filter-column">
<div v-for="(v, k) in data" :key="k">
<block v-if="k==filterIndex">
<p v-for="(vv, kk) in v['options']" :key="kk" :class="filterSelect[v.key] == vv.key ?'active':''" @click.stop="selectItem(v.key ,vv.key)">
<span>{{vv.name}}</span>
</p>
</block>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
data: [],
// 当前点击选中的筛选类目
filterIndex: "-1",
// 是否展开筛选项
filterShow: false,
//已选中的项
filterSelect: {
}
}
},
// filterData:所有的数据(必填参数) currenSelect:已选在数据(可选参数)
props: ['filterData', 'currenSelect'],
onLoad() {
var total = this.filterData;
console.log(total);
if (total) {
this.data = this.filterData;
// 初始化默认选中的选项
total.forEach(element => {
var key = element['key'];
console.log(key);
var value = element['options'] ? element['options'][0]["key"]: "";
this.filterSelect[key] = value;
});
}
},
methods: {
// 筛选条目被点击
itemClicked(k) {
this.filterIndex = k;
if (!this.filterShow) {
this.filterShow = true;
}
},
// 选中了某一个选项
selectItem(k, kk) {
this.filterSelect[k] = kk;
this.$emit("select", this.filterSelect);
this.filterShow = false;
this.filterIndex = "-1";
}
}
}
</script>
<style scoped>
.filter-box .filter {
height: 45px;
z-index: 101;
background-color: #fff;
}
.filter-box .filter p {
text-align: center;
flex: 1;
text-indent: -5px;
}
.filter-box .filter p::after {
content: "";
display: inline-block;
width: 4px;
height: 4px;
border-left: solid 1px #797979;
border-top: solid 1px #797979;
transform: rotate(-135deg);
position: relative;
top: -3px;
left: 5px;
transition: all .3s ease 0s;
}
.filter-box .filter p.active::after {
transform: rotate(45deg);
top: 0;
}
.filter-box .filter-overlay {
position: fixed;
width: 100%;
height: 0;
top: 45px;
left: 0;
background-color: transparent;
transition: background-color 0.5s ease;
z-index: 100;
}
.filter-box .filter-overlay.active {
background-color: rgba(0, 0, 0, 0.6);
height: 100%;
}
.filter-box .filter-column {
z-index: 101;
background-color: #fff;
}
.filter-box .filter-column p {
height: 40px;
line-height: 40px;
padding-left: 20px;
}
.filter-box .filter-column p span {
font-size: 16px;
color: #aaa;
}
.filter-box .filter-column p.active{
background: #f8f8fa;
color: #4b4b4b;
}
</style>
组件使用
// 模板引用
<template>
<div class="job index">
<Filter :filterData="filterData" @select="selectItem"></Filter>
</div>
</template>
如果需要设置默认参数 可以使用currenSelect
<Filter :filterData="filterData" :currenSelect="currenSelect" @select="selectItem"></Filter>
//JS:
mehtods: {
setFilter() {
var data = [
{
name: '经验',
key:'jingyan',
options: [
{"key": "0", "name": "不限"},
{"key": "1", "name": "应届生"},
{"key": "2", "name": "1年以内"},
{"key": "3", "name": "1-3年"}
]
},
{
name: '学历',
key:'xueli',
options: [
{"key": "0", "name": "不限"},
{"key": "1", "name": "初中及以下"},
{"key": "2", "name": "中专"},
{"key": "3", "name": "高中"}
]
},
{
name: '薪资',
key:'xinzi',
options: [
{"key": "0", "name": "不限"},
{"key": "1", "name": "3K以下"},
{"key": "2", "name": "3-5K"},
{"key": "3", "name": "5-8K"}
]
},
{
name: '经验',
key:'jingyan',
options: [
{"key": "0", "name": "不限"},
{"key": "1", "name": "无经验"},
{"key": "2", "name": "1年以内"},
{"key": "3", "name": "1-3年"}
]
},
{
name: '行业',
key:'hangye',
options: [
{"key": "0", "name": "不限"},
{"key": "1", "name": "金融"},
{"key": "2", "name": "互联网"},
{"key": "3", "name": "服务"}
]
},
];
this.filterData = data;
// 如果想默认选中值。不设置则默认选中第一项
this.currenSelect = {
'xinzi': "3"
}
},
// 筛选中某项
selectItem(query) {
console.log(query);
// 根据业务需要进行数据请求即可
// 打印出对象: {jingyan: "0", xueli: "0", xinzi: "2", hangye: "0"}
},
}
结语
前端的轮子还是比较多的,需要经常总结的。之前经常看别人写博客,之前一直没有静下来写,只是随手记在OSChina开源中国的笔记里,因为只是自己看所以写的比较乱。把这些代码写下来发布后能给自己一个约束,要写的完整并且能让其他人看得懂,能让自己学到更多的。