vue 封装一行省略 多行扩展组件 实现按钮点击展开收起功能

5 篇文章 0 订阅
2 篇文章 0 订阅

在实际开发中 我们经常会遇到一行省略的需求, 相信这种样式 大家早就滚瓜烂熟了, 但是有时产品会让我们在边上加个按钮, 点击按钮还要能多行显示具体内容:
在这里插入图片描述

不好意思 放错图片了…

大概是这样的:
在这里插入图片描述
这里会涉及到两个需求:

1.如何让按钮动态控制一行,多行之间的转化
– 1.1 通过控制父级的高度和样式, 来实现扩展功能(一行高度固定, 多余省略 / 多行高度auto)
2.屏幕大小动态变化时, 内容可能会超出 也可能不会, 此时需要动态的控制按钮的显示
– 2.1 添加屏幕自适应

HTML结构:

<template>
    <div class="expand-bar">
		<---------------------------------------- 动态添加class类来实现一行/多行切换 ↓ -->
        <div ref="container" :class="['content-container', {'content-expand': expand}]">
            <span ref="content">{{ content }}</span>
        </div>
        <span v-if="expandShow" class="action" @click="expand = !expand">
            <a-icon v-if="!expand" type="down" />
            <a-icon v-else type="up" />
        </span>
    </div>
</template>

vue.js:

<script lang='ts'>
import Vue from 'vue';
import { Icon } from 'ant-design-vue'; // 这边icon用的ant-design-vue的
import { debounce } from 'lodash';

Vue.use(Icon);

export default Vue.extend({
	// 具体内容:
    props: {
        content: {
            type: String,
            required: true,
        },
    },
    data() {
        return {
            expandShow: false, // 是否显示按钮
            expand: false, // 是否展开
        };
    },
    mounted() {
        this.watchContentWidth();
        // 添加屏幕自适应事件(这边做一个防抖的优化)
        window.addEventListener('resize', debounce(this.watchContentWidth, 300));
    },
    methods: {
        watchContentWidth() {
            const contentWidth = (this.$refs.content) as HTMLElement;
            const containerWidth = (this.$refs.container) as HTMLElement;
            if (contentWidth && containerWidth) {
                // 注意: span只能获取到offsetWidth 没有clientWidth
                // 比较内容的width和父容器的width, 判断是否超出
                this.expandShow = contentWidth.offsetWidth > containerWidth.offsetWidth;
            }
        },
    },

});
</script>

css:

<style lang='scss' scoped>
.expand-bar {
    position: relative;
    padding-right: 25px;
}
/** 一行显示的样式 **/
.content-container {
    display: inline-block;
    height: 20px;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/** 多行展开的样式 **/
.content-expand {
    height: auto;
    white-space: unset;
    overflow: unset;
}
.action {
    display: inline-block;
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    border: 1px solid #ccc;
    cursor: pointer;
    text-align: center;
}
</style>
注意和总结:

1. 通过比较span的宽度和父级的宽度, 来判断是否会超出父级宽度, 动态的给元素添加不同的类样式(超出就一行省略)
2. 通过css控制父级的高度 来实现展开功能(多行高度auto, 取消强行一行显示)
3. 添加屏幕自适应来动态控制按钮的显示和隐藏
4. 之所以使用span来放内容, 是因为span是行内元素, 其offsetWidth就是内容的真实宽度

好了, 今天就分享到这里啦~ 感谢大家!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值