在做列表篩選的時(shí)候經(jīng)常會(huì)按照不同的維度來(lái)過(guò)濾篩選數(shù)據(jù),多標(biāo)簽可供選擇就比較常見(jiàn),但是標(biāo)簽較多時(shí),就涉及到選項(xiàng)標(biāo)簽的展開(kāi)與折疊,這與展示區(qū)域、選項(xiàng)個(gè)數(shù)有關(guān)系,下面的實(shí)現(xiàn)就是解決了頁(yè)面寬度不確定、標(biāo)簽個(gè)數(shù)不確定、標(biāo)簽寬度不確定時(shí)的自動(dòng)折疊。
效果示意
實(shí)現(xiàn)思路:
- 選項(xiàng)展示區(qū)采用flex布局,允許換行;
- 選項(xiàng)高度固定,默認(rèn)狀態(tài)下,選強(qiáng)展示區(qū)的高度就是單個(gè)選項(xiàng)的高度;
- 采用展示區(qū)域的max-height來(lái)控制展開(kāi)、收起狀態(tài);
- 監(jiān)聽(tīng)到選項(xiàng)數(shù)組變化、瀏覽器窗口大小變化時(shí),重新判斷是否需要展示“更多”
- 采用子選項(xiàng)的長(zhǎng)度總和與選項(xiàng)展示區(qū)域?qū)挾缺容^的方式確定選項(xiàng)是否換行,是否要顯示“更多”
主要特點(diǎn):
1.不需要考慮選項(xiàng)的個(gè)數(shù),即展開(kāi)、收起操作時(shí),選項(xiàng)數(shù)組不會(huì)變化,不需要干預(yù);
2.采用CSS實(shí)現(xiàn)樣式的控制,選項(xiàng)寬度無(wú)限制,按需修改樣式可實(shí)現(xiàn)等寬、不等寬的需求;
3.可實(shí)時(shí)按照瀏覽器窗口大小來(lái)調(diào)整布局,并按需展示“更多”;
4.不同的需求,包括PC、手機(jī)的不同要求,可用css來(lái)調(diào)整。
主要實(shí)現(xiàn)如下(示例代碼是作為一個(gè)可復(fù)用組件方式實(shí)現(xiàn)的):
<template>
<div class="searchbar-container">
<span class="condition-title">{{ title }}</span>
<div ref="search-option-container" :class="['search-option-container', isExpand ? 'search-option-container-expand' : '']">
<div class="condition-option-frame">
<span :class="['condition-option', value == '' ? 'condition-option-selected' : '']" @click="handleSelect('')">全部</span>
</div>
<div class="condition-option-frame" v-for="(op, index) in options" :key="index" :content="op" @click="handleSelect(`${op}`)">
<span :class="[`${optionClassName}`, 'condition-option', (optionValueKey ? op[optionValueKey] : op) === value ? 'condition-option-selected' : '' ]">{{ optionlabelKey ? op[optionlabelKey] : op }}</span>
</div>
</div>
<div class="condition-option-more">
<div v-if="showToggle" @click="handleMore">
{{ isExpand ? '收起' : '更多'}}<i :class="[isExpand ? 'el-icon-arrow-up' : 'el-icon-arrow-down']"></i>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SearchOptionsAutoFold',
props: {
title: {
type: String,
default: '工業(yè)大類'
},
prop: {
type: String,
default: ''
},
value: {
type: String,
default: ''
},
optionClassName: {
type: String,
default: ''
},
options: {
type: Array,
default: function () {
return ["煤炭開(kāi)采和洗選業(yè)", "石油和天然氣開(kāi)采業(yè)", "黑色金屬礦采選業(yè)", "有色金屬礦采選業(yè)", "非金屬礦采選業(yè)", "其他采礦業(yè)", "農(nóng)副食品加工業(yè)", "食品制造業(yè)", "飲料制造業(yè)", "煙草制品業(yè)", "紡織業(yè)", "紡織服裝、鞋、帽制造業(yè)", "皮革、毛皮、羽毛(絨)及其制品業(yè)", "木材加工及木、竹、藤、棕、草制品業(yè)", "家具制造業(yè)", "造紙及紙制品業(yè)", "印刷業(yè)和記錄媒介的復(fù)制", "文教體育用品制造業(yè)", "石油加工、煉焦及核燃料加工業(yè)", "化學(xué)原料及化學(xué)制品制造業(yè)", "醫(yī)藥制造業(yè)", "化學(xué)纖維制造業(yè)", "橡膠制品業(yè)", "塑料制品業(yè)", "非金屬礦物制品業(yè)", "黑色金屬冶煉及壓延加工業(yè)", "有色金屬冶煉及壓延加工業(yè)", "金屬制品業(yè)", "通用設(shè)備制造業(yè)", "專用設(shè)備制造業(yè)", "交通運(yùn)輸設(shè)備制造業(yè)", "電氣機(jī)械及器材制造業(yè)", "通信設(shè)備、計(jì)算機(jī)及其他電子設(shè)備制造業(yè)", "儀器儀表及文化、辦公用機(jī)械制造業(yè)", "工藝品及其他制造業(yè)", "廢棄資源和廢舊材料回收加工業(yè)", "電力、熱力的生產(chǎn)和供應(yīng)業(yè)", "燃?xì)馍a(chǎn)和供應(yīng)業(yè)", "水的生產(chǎn)和供應(yīng)業(yè)"];
}
},
optionlabelKey: {
type: String,
default: ''
},
optionValueKey: {
type: String,
default: ''
},
},
data() {
return {
showToggle: false,
isExpand: false
}
},
watch: {
options(val, oldVal) {
if (val.length > 0) {
this.refreshViews();
}
}
},
mounted() {
if (this.options.length > 0) {
this.refreshViews();
}
window.onresize = () => {
this.refreshViews();
}
},
methods: {
handleMore() {
this.isExpand = !this.isExpand
},
handleSelect(value) {
this.$emit('handleSelect', this.prop, value)
},
refreshViews() {
this.$nextTick(() => { // 頁(yè)面渲染完成后的回調(diào)
let containerClientWidth = this.$refs['search-option-container'].clientWidth;
let length = this.$refs['search-option-container'].children.length;
console.log('containerClientWidth==>' + containerClientWidth)
console.log('length==>' + length)
let totalWidth = 0;
for (let i = 0; i < length; i++) {
totalWidth = totalWidth + this.$refs['search-option-container'].children[i].clientWidth
}
// 存在更多選項(xiàng)
this.showToggle = totalWidth > containerClientWidth;
})
}
}
}
</script>
<style scoped>
.searchbar-container {
padding: 4px 0px;
display: flex;
align-items: center;
}
.condition-title {
font-weight: bold;
width: 5em;
flex-shrink: 0;
}
.search-item-container {
flex-grow: 1;
display: flex;
flex-wrap: wrap;
}
.search-option-container {
flex-grow: 1;
display: flex;
flex-wrap: wrap;
max-height: 30px;
overflow: hidden;
}
.search-option-container-expand {
max-height: 500px;
}
.condition-option-frame {
padding: 0px 8px;
margin: 0px;
height: 30px;
display: flex;
align-items: center;
}
.condition-option {
/* 是否需要等長(zhǎng) */
width: 5em;
display: -webkit-box !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
text-align: center;
cursor: pointer;
}
/* 單個(gè)字母 */
.condition-option-letter {
width: 1em;
}
.condition-option-selected {
color: var(--color-primary);
font-weight: bold;
}
.condition-option-more {
padding-top: 5px;
width: 66px;
align-self: baseline;
flex-shrink: 0;
color: var(--color-primary);
}
.condition-option-more > div {
display: flex;
justify-content: flex-end;
align-items: center;
}
/* 窄屏設(shè)備 */
@media only screen and (max-width: 992px) {
}
</style>