仅做记录,未整理格式
css部分未完全,每个筛选条件为固定宽度
实现效果
单行筛选条件时不触发更多按钮,且做占位处理
多行筛选条件时默认收起
同时设定最大/最小宽度并监听该组件宽度变化
filter.vue组件
<template>
<div :class="`new-filter-block ${!showMoreFilter?'new-filter-block_hidden':''}`">
<div id="resize-element" ref="filter" class="new-filter-slotBox" >
<slot />
<div v-show="seizeList.length" v-for="(item, index) in seizeList" :key="index" class="new-filter-item_seize"/>
</div>
<div class="new-filter-btnBox">
<el-button class="new-second-btn" @click="search" >搜索</el-button>
<el-button @click="reset" >重置</el-button>
<div :class="`new-filter-more ${!moreFilter?'new-filter-more_hidden':''}`" @click="handleMoreFilter" >
{{ showMoreFilter ? '收起' : '更多' }} <i class="el-icon-arrow-down" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'LFilters',
emits: ['search', 'reset'],
props: {
},
data() {
return {
showMoreFilter: false,
moreFilter: false,
observer: null,
oldWidth: 0,// 记录下旧的数据,避免重复触发回调函数
seizeList:[],//空白占位数据
filterCount:0,//筛选条件的个数,保证不受占位符的影响
}
},
mounted() {
this.filterCount=this.$refs.filter.children.length
const resizeObserver = new ResizeObserver(entries => {
// 回调
const curBoxWidth = entries[0].contentBoxSize[0].inlineSize
this.handleFilterResize(curBoxWidth)
})
// 监听筛选条件盒子
resizeObserver.observe(this.$refs.filter)
},
methods: {
/**
* 高级筛选
*/
handleMoreFilter() {
this.showMoreFilter = !this.showMoreFilter
},
// 触发搜索事件
search() {
this.$emit('search')
},
reset() {
this.$emit('reset')
},
// 处理筛选条件宽度变化
handleFilterResize(boxW) {
if (!boxW || this.oldWidth === boxW) return
this.oldWidth = boxW
const itemMinW = 280
const marginR = 10
const filterItemW = itemMinW + marginR
const rowCount = Math.floor(boxW / filterItemW)
const filterCount = this.filterCount
this.moreFilter = filterCount > rowCount
if(this.moreFilter){//设置占位列表长度,最多为rowCount
let excessiveCount=filterCount%rowCount
this.seizeList=new Array(rowCount-excessiveCount).fill('')
}
}
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/variables.scss';
::v-deep{
.el-input__inner,
.el-date-editor,
.el-range-separator,
.el-input__icon {
height: 32px !important;
line-height: 32px !important;
}
.el-select, .el-cascader, .el-input {
width: 100%;
min-width: 140px;
.el-input__inner{
padding-right: 12px !important;
}
}
.el-cascader__tags {
// display: none;
.el-tag{
display: none;
}
}
.el-date-editor {
width: 100%;
.el-range-separator {
width: 16px;
padding: 0;
}
}
}
.new-filter-block{
padding: 12px;
background-color: #F8F8F8;
display: flex;
// flex-wrap: wrap;
.new-filter-slotBox{
flex: 1;
display: flex;
flex-wrap: wrap;
.new-filter-item_seize,
.new-filter-item{
flex: 1;
min-width: 280px;
max-width: 340px;
margin-bottom: 10px;
display: flex;
flex-wrap: nowrap;
align-items: center;
font-size: 14px;
color: $text-col-3;
margin-right: 10px;
}
.new-filter-itemLabel {
width: 88px;
text-align: right;
margin-right: 12px;
word-break: keep-all;
}
}
.new-filter-btnBox{
display: flex;
font-size: 12px !important;
.el-button {
width: 54px;
height: 32px;
padding: 0;
}
.new-filter-more{
width: 54px;
height: 32px;
line-height: 32px;
margin-left: 10px;
color:$blue;
cursor: pointer;
}
.new-filter-more_hidden{
visibility: hidden;
}
}
}
.new-filter-block_hidden{
height: 56px;
overflow: hidden;
}
</style>
使用
<LFilters @search="()=>search()" @reset="()=>emptyQuery()" >
//...等宽筛选条件
</LFilters>