引入:实现一个带有筛选功能的搜索框,封装成组件;
搜索框长这样子:
点击右侧筛选图标后弹出层,长这样子:
实际应用中有多组筛选条件,这里为了举栗子就展示一组;
预览:
实现思路:
- css 样式大致布局;
- 选中和取消选中的效果、样式切换等;
- 多选的功能;
- 多组筛选条件的多选功能;
需要给父组件传递的数据有:
- 点击搜索按钮时传【输入的内容】;
- 点击查询按钮时传【选择的查询条件】
进一步的实现:
- 首先写好基础的静态样式;
- 当要开始写功能的时候,可以换成接口调用的动态数据,从父组件传入;
- 先写单选,动态绑定
class
样式来实现选中之后的样式:
:class="{ 'seled-btn': venSeled.includes(index) }"
- 选中后考虑还需要取消,因为条件筛选是多选的,所以是将下标保存进数组中:
if (this.typeSeled.includes(index)) {
// 筛掉【当前选中的】和【数组中】不一致的下标,即只保存相等的
this.typeSeled = this.typeSeled.filter(item => item != index)
} else {
// 未选中就添加进数组中
this.typeSeled.push(index)
}
代码:
<!--
带条件筛选的搜索框组件
-->
<template>
<view class="container">
<u-popup v-model="show" mode="top" border-radius="14" length="50%">
<view class="wrap">
<view class="wrap-top">
<p>类型:</p>
<view class="item">
<view v-for="(item, index) in typeList" :key="index" @click="seledBtn(index, 'type', item)"
class="btn sel-btn" :class="{ 'seled-btn': typeSeled.includes(index) }">{{ item }}
</view>
</view>
</view>
</view>
<view class="wrap-foot" style="display: flex;">
<u-button @click="reset">重置</u-button>
<u-button type="primary" @click="searchRes">查询</u-button>
</view>
</u-popup>
<u-search @custom="searchClick" :show-action="true" v-model="val" placeholder="请输入" shape="square"
:border="border" :animation="false"></u-search>
<img class="right-icon" @click="show = true" src="../../../../static/gzt/filter.png" width="18" height="18" alt="">
</view>
</template>
<script>
export default {
props: {
vehList: {
type: Array
},
workList: {
type: Array
}
},
data() {
return {
typeList: ['类型1', '类型2'],
// 是否点击
typeSeled: [],
val: '',
border: true,
show: false
}
},
methods: {
// 点击搜索
searchClick() {
this.$emit('singleClick', this.val)
},
// 选中某一个条件
seledBtn(index, type, itemVal) {
// console.log('type', type);
if (type == 'type') {
if (this.typeSeled.includes(index)) {
// 筛掉【当前选中的】和【数组中】不一致的下标
this.typeSeled = this.typeSeled.filter(item => item != index)
} else {
// 未选中就添加进数组中
this.typeSeled.push(index)
}
}
},
// 点击重置
reset() {
this.typeSeled = []
},
// 点击查询
searchRes() {
let typeRes = []
// 整理数据
// typeList typeSeled
this.typeList.forEach((item, index) => {
this.typeSeled.forEach(item1 => {
if (index == item1) {
typeRes.push(item)
}
})
})
// 给父组件发送选择的查询条件
this.$emit('filterSearch', typeRes)
}
}
}
</script>
样式参考:
<style lang="scss">
.wrap {
padding: 0 15px 60px 15px;
// background-color: pink;
.wrap-top {
margin-top: 10px;
>p {
color: #4F4B46;
}
.item {
display: flex;
flex-wrap: wrap;
margin-top: 10px;
}
// btn的共有样式
.btn {
margin-top: 5px;
margin-right: 8px;
width: 30%;
text-align: center;
padding: 5px;
border-radius: 8px;
}
// 未被选中的样式
.sel-btn {
background-color: #F5F7F8;
color: #717171;
border: 1px solid #F0F0F0;
}
// 被选中的样式
.seled-btn {
background-color: #EDF5FF;
border: 1px solid #6AA4EC;
color: #6AA4EC;
}
}
}
::v-deep .u-btn--default {
color: #b7b8b8 !important;
border-radius: 0px;
}
.wrap-foot {
position: fixed;
margin-top: 5px;
bottom: -1px;
width: 100%;
}
::v-deep uni-button {
width: 100%;
}
.container {
display: flex;
background-color: white;
padding: 5px;
border-radius: 8px;
.right-icon {
margin-top: 7px;
margin-left: 10px;
}
}
::v-deep .u-action-active {
color: gray;
}
::v-deep .u-content {
border: 1px solid #ccc !important;
}
</style>
关于有好几组筛选条件时怎么进行选择,我的方法是,在 seledBtn
函数里写一个循环,以 0-几组筛选条件的长度进行循环,最终数组只有一个,给这个数组里对应下标里进行增加或删除,下标对应的是第几组筛选条件,比如我有3组,最终数组就是:[[],[],[]] 这么一个嵌套数组;