vue实现移动端常见的文本展开收起功能

12,096 阅读2分钟

1.功能介绍

最近开发移动端项目遇到了这么一个需求,就是列表中文本最多三行,超出部分省略,并显示展开收起按钮,如果文本没有超出三行则不显示展开收起按钮,如图:

2.需求分析

刚看到这个需求的时候第一个反应就是,怎么判断文本的高度是否已经超过三行?页面刚加载的时候默认全部显示,判断如果高度超过某一个值就让他隐藏?还没写就觉得不靠谱:

  • 1.这是一个列表还有滚动加载,每次都去循环计算这些高度显得不太优雅(主要实现起来也比较麻烦);
  • 2.页面刚进来的时候全部显示,判断好以后再去隐藏,一两条数据还好,数据量大的话很可能进来的时候页面会闪一下

后来各种审查元素,各种修改html,终于发现了一个好办法,那就是在div 中添加一个span 然后给div设置超出三行省略,这时候就可以获取到文本高度和div高度了,如图:

这样的话我只要在mounted中判断这两个高度就知道是不是应该展示展开收起按钮了,后面的点击事件什么的都是浮云,有了思路,那就简单很多了。

3.代码实现

其实还有一个小问题,那就是列表中这么多数据,我怎么一个一个的判断呢?其实非常简单,封装成一个组件在组件中的mounted中判断就好了。下面就是我封装的组件代码(复制黏贴改样式就可以用的那种代码)

<template>
  <div class="text-box">
    <div :class="['txt', { 'over-hidden': !unfold }]" ref="textBox">
      <span ref="spanBox">{{content}}</span>
    </div>
    <div class="btn" v-if="ifOver" @click="unfold = !unfold">{{unfold ? '收起' : '展开'}}</div>
  </div>
</template>
<script>
export default {
  name: "text-box",
  data() {
    return {
      ifOver: false, // 文本是否超出三行,默认否
      unfold: false // 文本是否是展开状态 默认为收起
    };
  },
  props: {
    content: {
      type: String,
      default: ""
    }
  },
  mounted() {
    // 判断是否显示展开收起按钮
    this.ifOver = this.$refs.spanBox.offsetHeight > this.$refs.textBox.offsetHeight
  }
};
</script>
<style scoped>
.txt {
  font-size: 16px;
  color: #333;
  margin-bottom: 5px;
}
.over-hidden {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
.btn {
  color: red;
}
</style>

4.总结

这个功能还是很常见的,可能好多前端程序员也遇到过这类需求,所以想着还是分享出来。大家如果有更简单或者更好的建议也可以提出来,互相交流学习。^-^