vue 富文本展开详情

38 阅读1分钟
<template>
  <div class="parse-container" @click="stopLink">
    <div v-html="displayContent"></div>
    <div class="operation" v-if="isOperation">
      <span @click="toggleExpand">
        展开详情
        <van-icon class="icon" :class="{top: isExpanded}" name="arrow-down" />
      </span>
    </div>
  </div>
</template>
<script>
  import { ref, watch } from "vue";
  export default {
    name: "Parse",
    props: {
      html: {
        type: String,
        default: ""
      },
      isOperation: {
        type: Boolean,
        default: true
      }
    },
    setup(props) {

      // 显示内容
      const displayContent = ref("");
      // 展开收起
      const isExpanded = ref(false);


      watch(() => props.html, () =>   {
        updateDisplayContent()
      }, { immediate: true })

      // 切换展开
      function toggleExpand() {
        isExpanded.value = !isExpanded.value;
        updateDisplayContent()
      }

      // 展示内容
      function updateDisplayContent () {
        if (!props.isOperation) {
          displayContent.value = props.html;
          return;
        }

        let arr = props.html.split("</p>")
        // 默认折叠状态,只显示部分内容
        const truncatedContent = arr[0] + "...</p>";
        console.log(truncatedContent);
        displayContent.value = isExpanded.value ? props.html : truncatedContent;
      }

      // 禁止点击
      function stopLink(e) {
        e.preventDefault();
        e.stopPropagation();
      }

      return {
        stopLink,
        isExpanded,
        toggleExpand,
        displayContent
      }
    }
  }
</script>

<style scoped lang="less">
  .parse-container {
    width: 100%;
    overflow-wrap: break-word;
    word-break: break-all;
    /deep/ * {
      max-width: 100% !important;
      box-sizing: border-box;
      overflow-wrap: break-word;
      word-break: break-all;
      padding-left: 0!important;
      padding-right: 0!important;
      margin-left: 0!important;
      margin-right: 0!important;
    }

    /deep/ img {
      max-width: 100% !important;
    }

    .operation {
      text-align: right;
      color: #4A90E5;
      .icon {
        transition: transform 1s;
      }
      .top {
        transform: rotate(180deg);
      }
    }
  }
</style>