标签超过一行后折叠并显示控制折叠/展开按钮(标签宽度不固定)

标签宽度不固定,想要实现超出一行后就自动折叠,并在后面跟上折叠/展开按钮,当标签总长度不足一行时不显示按钮,超过一行时折叠并显示按钮

话不多说,直接上代码

<template>
      <ul class="sub-nav">
        //这块的v-show显示条件是data,isFold(属于展开状态)||(或者)index(下标)<data.foldIndex(当前我所记录单行可以展示的数量)
            <li v-for="(item,index) in data.keywordList" :key="index" v-show="index < data.foldIndex||data.isFold"
                :class="data.keyword==item?'active-li sub-nav-list':'sub-nav-list'" @click="handleCutKey(item)">
                {{item}}
            </li>
            <li class="btn" ref="fold" @click="data.isFold=!data.isFold"
                :style="data.isFold?{position:'unset'}:{position:'absolute'}">
                {{data.isFold?'折叠':'展开'}}<img :style="{transform:data.isFold?'rotate(90deg)':'rotate(-90deg)'}"
                    src="@/assets/image/返回键.png" alt="">
            </li>
        </ul>
</template>
<script setup lang="ts">
    const data = reactive({
        // 关键词分类
    keywordList: string[] = [];
    // 当前选中的关键词
    keyword: string = '';
    // 是否折叠关键词
    isFold: boolean = false;
    // 折叠展示到的下标
    foldIndex: number = 100;
    })
    const fold = ref < HTMLElement | null > (null)
    onMounted(() => {
        getData()
    })
// 获取数据
    const getData = () => {
        data.keywordList = ['热门', '人物', '萌宠', '美妆', '足球盛宴', '旅行', '汽车', '穿搭']
        data.keyword = data.keywordList[0]
        let boxWidth = document.querySelector('.sub-nav').offsetWidth
            let arr = document.querySelectorAll('.sub-nav-list')
            let btnWidth = fold.value.offsetWidth
            variable(boxWidth, arr, btnWidth)
                .then(res => {
                    data.foldIndex = res
                    console.log(res)
                })
                .catch(error => {
                    // 此处不足一行时我将按钮隐藏了
                    fold.value.style.display = error
                    console.error(error);
                });
    }
// 封装可折叠标签组件
    const variable = (boxWidth: number, arr: HTMLElement[] | null, btnWidth: number) => {
        // boxWidth  -- 盒子宽度          arr  -- 要处理的dom列表     btnWidth  -- 展开/折叠按钮的宽度
        return new Promise((resolve, reject) => {
            let array = Array.from(arr) //
            // 求出元素叠加后的总长度
            // 使用reduce方法计算总和
            let sum = array.reduce((acc, obj) => {
                return acc + obj.offsetWidth;
            }, 0);
            if (sum > boxWidth) {
                // 元素总长度大于盒子宽度
                let total = 0;
                let index = 0;
                for (let i = 0; i < array.length; i++) {
                    total += array[i].offsetWidth;
                    if (total >= boxWidth - btnWidth) {
                        index = i;
                        break;
                    }
                }
                // 返回应该展示的标签数量
                resolve(parseInt(index));
            } else {
                // 元素总长度小于盒子宽度
                console.log('小')
                reject('none');
            }

        });
    }
// 切换关键词
    const handleCutKey = (item: string) => {
        data.keyword = item
    }
</script>
<style scoped lang="scss">
.sub-nav {
            width: 100%;
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            margin-top: 0.1rem;
            padding: 0 0.1rem;
            position: relative;

            li {
                display: flex;
                align-items: center;
                //此处记得用padding来留出和右边标签之间的距离
                padding-right: .2rem;
                font-size: .12rem;
                white-space: nowrap;
                color: #999999;
                cursor: pointer;
                padding-bottom: .1rem;
                user-select: none;
            }

            .active-li {
                color: #E80000;
                padding-bottom: .1rem;
            }

            .btn {
                color: #5764FF;
                position: absolute;
                right: 0;
                top: 0;

                img {
                    margin-left: 0.05rem;
                    width: 0.06rem;
                    transform: rotate(-90deg);
                }

            }
        }
</style>

现在单位经常会出这样的需求,有这种交互方式,功能很小,但挺麻烦,今天 索性就直接简单封装了一下,主要方法variable(),完整代码就这样,有问题评论区联系吧

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值