在实际开发中 我们经常会遇到一行省略的需求, 相信这种样式 大家早就滚瓜烂熟了, 但是有时产品会让我们在边上加个按钮, 点击按钮还要能多行显示具体内容:
不好意思 放错图片了…
大概是这样的:
这里会涉及到两个需求:
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就是内容的真实宽度
好了, 今天就分享到这里啦~ 感谢大家!