美文网首页Vue.js专区一个后端开发者的前端学习笔记vue
Vue 中文本内容超出规定行数后展开收起的处理

Vue 中文本内容超出规定行数后展开收起的处理

作者: Ethan_zyc | 来源:发表于2018-07-21 18:08 被阅读1848次

    Vue 中文本内容超出规定行数后展开收起的处理

    文字比较难解释,直接看图应该就懂是要做什么了。

    image

    需求

    工作中遇到的,需求就是超过四行得有个展开按钮,点击展开显示所有内容,不超过四行的话就不需要这个按钮并显示所有内容。


    思路

    1. 首先得判断文本自否超过四行,因为这些一般都是是前端异步请求然后后端发送过来,在组长的指导下,使用了 Vue 中的 nextTick 来监听 DOM 中是数据变化。
    2. 接下来主要是 css 上的思路,其实上图可以分为两部分,如下图,标号1的部分展示前面三行,标号为2的部分会根据1的行数判断缩进的大小,然后展示第四行。最后通过背景色的控制让两者看上去是一段文字。
    image

    代码

    核心代码是中间那部分,其他的不用关注

    <template>
      <div>
        <div style="text-align: center">{{title}}</div>
        <div class="top-prove">为了证明楼下的那货不会对我造成影响</div>
        <div :class="showTotal ? 'total-introduce' : 'detailed-introduce'">
          <div class="intro-content" :title="introduce" ref="desc">
            <span class="merchant-desc" v-if="introduce">
              {{introduce}}
            </span>
            <div class="unfold" @click="showTotalIntro" v-if="showExchangeButton">
              <p>{{exchangeButton ? '展开' : '收起'}}</p>
            </div>
          </div>
        </div>
        <div class="bottom-prove">为了证明楼上的那货不会对我造成影响</div>
        <div class="change-buttom">
          <div class="long" @click="tryLong">点这试试一段比较长的文字</div>
          <div class="short" @click="tryShort">点这试试一段比较短的文字</div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'Spread',
      data () {
        return {
          title: '演示展开收起',
          introduce: '',
          // 是否展示所有文本内容
          showTotal: true,
          // 显示展开还是收起
          exchangeButton: true,
          // 是否显示展开收起按钮
          showExchangeButton: false,
          rem: ''
        };
      },
      mounted () {
        this.init();
      },
      methods: {
        showTotalIntro () {
          console.log(this.showTotal);
          this.showTotal = !this.showTotal;
          this.exchangeButton = !this.exchangeButton;
        },
        getRem () {
          console.log('getRem');
          const defaultRem = 16;
          let winWidth = window.innerWidth;
          console.log('winWidth:' + winWidth);
          let rem = winWidth / 375 * defaultRem;
          return rem;
        },
        init () {
          this.introduce = '拥有财富、名声、权力,这世界上的一切的男人--哥尔·D·罗杰,在被行刑受死之前说了一句话,让全世界的人都涌向了大海。“想要我的宝藏吗?如果想要的话,那就到海上去找吧,我全部都放在那里。”,世界开始迎接“大海贼时代”的来临。拥有财富、名声、权力,这世界上的一切的男人 “海贼王”哥尔·D·罗杰,在被行刑受死之前说了一句话,让全世界的人都涌向了大海。“想要我的宝藏吗?如果想要的话,那就到海上去找吧,我全部都放在那里。”,世界开始迎接“大海贼时代”的来临。';
        },
        tryLong () {
          let longIntroduce = 'Vue是一套用于构建用户界面的渐进式框架。Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。';
          if (this.introduce !== longIntroduce) {
            this.showExchangeButton = false;
            this.showTotal = true;
            this.introduce = longIntroduce;
          }
        },
        tryShort () {
          let shortIntroduce = 'Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。';
          if (this.introduce !== shortIntroduce) {
            this.showExchangeButton = false;
            this.showTotal = true;
            this.introduce = shortIntroduce;
          }
        }
      },
      watch: {
        'introduce': function () {
          this.$nextTick(function () {
            console.log('nextTick');
            // 判断介绍是否超过四行
            let rem = parseFloat(this.getRem());
            console.log('watch 中的rem', rem);
            if (!this.$refs.desc) {
              console.log('desc null');
              return;
            }
            let descHeight = window.getComputedStyle(this.$refs.desc).height.replace('px', '');
            console.log('descHeight:' + descHeight);
            console.log('如果 descHeight 超过' + (5.25 * rem) + '就要显示展开按钮');
            if (descHeight > 5.25 * rem) {
              console.log('超过了四行');
              // 显示展开收起按钮
              this.showExchangeButton = true;
              this.exchangeButton = true;
              // 不是显示所有
              this.showTotal = false;
            } else {
              // 不显示展开收起按钮
              this.showExchangeButton = false;
              // 没有超过四行就显示所有
              this.showTotal = true;
              console.log('showExchangeButton', this.showExchangeButton);
              console.log('showTotal', this.showTotal);
            }
          }.bind(this));
        }
      }
    };
    </script>
    
    <style lang="less" scoped rel="stylesheet/less">
      .top-prove {
        height: 100px;
        width: 100%;
        background: #dddddd;
        text-align: center;
        line-height: 100px;
      }
      .total-introduce {
        height: auto;
        overflow: hidden;
        font-size: 14px;
        color: #434343;
        margin: 10px;
        .intro-content {
          .merchant-desc {
            width: 100%;
            line-height: 21px;
          }
        }
        .unfold {
          display: block;
          z-index: 11;
          float: right;
          width: 40px;
          height: 21px;
          p {
            margin: 0;
            line-height: 21px;
            color: #7fbe87;
          }
        }
      }
      .detailed-introduce {
        font-size: 14px;
        color: #434343;
        position: relative;
        overflow: hidden;
        margin: 10px;
        .intro-content {
          // 最大高度设为4倍的行间距
          max-height: 84px;
          line-height: 21px;
          word-wrap: break-word;
          /*强制打散字符*/
          word-break: break-all;
          background: #ffffff;
          /*同背景色*/
          color: #ffffff;
          overflow: hidden;
          .merchant-desc {
            width: 100%;
            line-height: 21px;
          }
          &:after,
          // 这是展开前实际显示的内容
          &:before {
            content: attr(title);
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            color: #434343
            // overflow: hidden;
          }
          // 把最后最后一行自身的上面三行遮住
          &:before {
            display: block;
            overflow: hidden;
            z-index: 1;
            max-height: 63px;
            background: #ffffff;
          }
          &:after {
            display: -webkit-box;
            -webkit-box-orient: vertical;
            overflow: hidden;
            height: 81px;
            /*截取行数*/
            -webkit-line-clamp: 4;
            text-overflow: ellipsis;
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
            /*行首缩进字符数,值为[(截取行数-1)*尾部留空字符数]*/
            text-indent: -12em;
            /*尾部留空字符数*/
            padding-right: 4em;
          }
          .unfold {
            z-index: 11;
            width: 40px;
            height: 21px;
            outline: 0;
            position: absolute;
            right: 0;
            bottom: 0;
            p {
              margin: 0;
              line-height: 21px;
              color: #7fbe87;
            }
          }
        }
      }
      .bottom-prove {
        height: 100px;
        width: 100%;
        background: #dddddd;
        text-align: center;
        line-height: 100px;
      }
      .change-buttom {
        font-size: 14px;
        color: #2371be;
        .long {
          text-align: 21px;
          text-align: center;
          height: 21px;
        }
        .short {
          text-align: 21px;
          text-align: center;
          height: 20px;
        }
      }
    </style>
    
    

    演示动画

    image

    另一种思路

    简书中i_May的方法,思路有些不同,也可以参考下。


    问题

    1. 工作中该页面打包到测试环境在微信中打开后,三个省略号消失了,问题还在找,找到了会及时更新。
    2. 因为符号可能会在行尾出现点显示问题,暂时还没找到解决办法,但出现概率较小,出现了也不影响。

    相关文章

      网友评论

      • 68d9307f75a3:你好,跟您一样的需求 但是我watch 监听的 introduce,不是一个单独的字段,而是有for循环,循环出来的一个item.info,这时候怎么监听呢?谢谢作者回复
        Ethan_zyc:@甜纯 那就监听循环的那个变量试试,记得加deep
      • 真干脆面:楼主 用了sass或者less的哇?
        真干脆面:@Ethan_zyc 谢谢楼主
        Ethan_zyc:对,用的 less
      • 3f09a321c769:你这个能处理分段的吗?就是文章是分好段落的,但是你不知道是几个段落
        Ethan_zyc:分段的话应该会有换行吧,可以靠这个判断吧
      • _52Hertz:写的很好,对我帮助很大,希望博主持续更新更多更好的文章
        Ethan_zyc:好的
      • 小虾米前端:有帮助了~多谢

      本文标题:Vue 中文本内容超出规定行数后展开收起的处理

      本文链接:https://www.haomeiwen.com/subject/wizhmftx.html