文字超出收起展开功能的实现(vue2)

1.编写展开收起组件

复制代码
 <template>
    <div class="text-clamp">
      <div class="text" :style="{height}">
        <span v-if="isVisible" class="btn" @click="toggle">{{isExpand ? '收起' : '... 展开'}}</span>
        <div ref="textRef" :style="commonStyle">
          <slot />
        </div>
      </div>
    </div>
  </template>
   
  <script>
  export default {
    name: "TextClamp",
    props: {
      fontSize: {
        type: Number,
        default: 14
      },
      lines: {
        type: Number,
        default: 1
      },
      lineHeight: {
        type: Number,
        default: 20
      },
      selectors: {
        type: String,
        default: ""
      }
    },
    data () {
      return {
        isExpand: false,
        isVisible: false,
        textHeight: 0
      };
    },
    computed: {
      height () {
        if (this.isExpand) {
          return this.$refs.textRef.clientHeight + 'px';
        } else {
          return Math.min((this.lines * this.lineHeight), this.textHeight) + 'px';
        }
      },
      commonStyle () {
        return {
          lineHeight: this.lineHeight + 'px',
          fontSize: this.fontSize + 'px',
        };
      }
    },
    mounted () {
      this.init();
      // 监听插槽变化
      const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          if (mutation.type === "characterData") {
            this.init();
          }
        });
      });
      observer.observe(this.$refs.textRef, {
        characterData: true,
        subtree: true,
        childList: true
      });
    },
    methods: {
      init () {
        this.isExpand = false;
        this.textHeight = this.$refs?.textRef?.clientHeight || 0;
        this.isVisible = this.textHeight > this.lines * this.lineHeight;
      },
      toggle () {
        this.isExpand = !this.isExpand;
        if (!this.isExpand && this.selectors) {
          const initEl = document.querySelector(this.selectors);
          setTimeout(() => {
            initEl.scrollIntoView({
              behavior: 'smooth',
              block: 'start',
              inline: 'center'
            });
          }, 97);
        }
      }
    }
  };
  </script>
   
  <style lang="scss" scoped>
  .text-clamp {
    display: flex;
    overflow: hidden;
  }
  .text {
    font-size: 20px;
    transition: 0.3s height;
  }
  .text::before {
    content: "";
    height: calc(100% - 20px);
    float: right;
  }
  .btn {
    float: right;
    clear: both;
    font-size: 12px;
    line-height: 14px;
    padding: 2px 6px;
    background: #1890ff;
    border-radius: 2px;
    color: #fff;
    cursor: pointer;
  }
  </style>

2.导入并注册组件

复制代码
import MyText from './textOver.vue';
export default {
    components: {
        MyText
    },
}

3.使用组件

复制代码
 <MyText :lines="2">{{ showText }}</MyText>

4.效果图

相关推荐
昔人'2 小时前
css 高度从 0 到 auto 的动画效果 `interpolate-size: allow-keywords`
前端·css
百思可瑞教育2 小时前
Vue 生命周期详解:从初始化到销毁的全过程剖析
前端·javascript·vue.js·前端框架·uni-app·北京百思可瑞教育·百思可瑞教育
IT_陈寒2 小时前
Python 3.12 新特性实战:10个性能优化技巧让你的代码快如闪电⚡
前端·人工智能·后端
Wiktok2 小时前
前后端开发Mock作用说明,mock.ts
前端·mock·vue3
冲!!2 小时前
SCSS 中的Mixins 和 Includes,%是什么意思
前端·css·scss
梦6503 小时前
CSS新特性
css
星语卿3 小时前
Vuetify:构建优雅Vue应用的Material Design组件库
前端·javascript·vue.js
wangbing11254 小时前
界面规范11-对话框
javascript·vue.js·elementui