多行文本的文字展示全部和收起功能

news2024/12/30 3:49:27

组件代码:

<template>
  <!-- 外层容器,使用相对定位 -->
  <div class="relative">
    <!-- 文本容器,根据 expanded 状态决定是否应用 line-clamp-4-->
    <div :class="{ 'line-clamp-4': !expanded }" ref="textContainer">
      {{ text }}
    </div>
    <!-- 展开/收起按钮,只有在文本需要折叠时才显示,使用绝对定位 -->
    <button
      v-if="isCollapsible"
      @click="toggleExpand"
      class="text-blue-500 absolute -right-6 bottom-0"
    >
      {{ expanded ? '收起' : '展开' }}
    </button>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'

// 定义组件的 props
const props = defineProps({
  text: {
    type: String,
    required: true
  },
  fontSize: {
    type: String,
    required: false,
    default: '12px'
  }
})

const expanded = ref(false)  // 控制文本是否展开
const isCollapsible = ref(false)  // 控制文本是否需要折叠
const textContainer = ref(null)  // 引用文本容器

// 切换展开/收起状态的函数
const toggleExpand = () => {
  expanded.value = !expanded.value
}

// 检查文本是否需要折叠的函数
const checkCollapsible = () => {
  nextTick(() => {
    const width = textContainer.value.clientWidth  // 获取文本容器的宽度
    const dummyElement = document.createElement('div')
    dummyElement.style.position = 'absolute'
    dummyElement.style.visibility = 'hidden'
    dummyElement.style.width = `${width}px`
    dummyElement.style.fontSize = props.fontSize  // 设置字体大小
    dummyElement.style.lineHeight = getComputedStyle(textContainer.value).lineHeight
    dummyElement.innerText = props.text
    document.body.appendChild(dummyElement)

    const lineHeight = parseInt(getComputedStyle(dummyElement).lineHeight)  // 获取行高
    const totalHeight = dummyElement.clientHeight  // 获取文本总高度
    document.body.removeChild(dummyElement)

    const maxHeight = lineHeight * 4 + 5  // 设定最大高度(假设最多显示4行)
    isCollapsible.value = totalHeight > maxHeight  // 判断是否需要折叠
  })
}

// 组件挂载时执行的操作
onMounted(() => {
  checkCollapsible()  // 检查文本是否需要折叠
  window.addEventListener('resize', checkCollapsible)  // 监听窗口大小变化,重新检查
})
</script>

<style scoped>
</style>

效果图:
在这里插入图片描述
在这里插入图片描述
优化版本,展开全部文字 展示在文本域后面。需要做一个截取文本操作。

<template>
  <div>
    <div ref="textContainer" :class="{ 'line-clamp-4': !expanded }">
      <span v-if="!expanded">{{ truncatedText }}</span>
      <span v-else>{{ text }}</span>
      <button v-if="isCollapsible" @click="toggleExpand" class="text-blue-500 ml-2">
        {{ expanded ? '收起' : '展开全部' }}
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'

// 定义组件的 props
const props = defineProps({
  text: {
    type: String,
    required: true
  },
  fontSize: {
    type: String,
    required: false,
    default: '12px'
  },
  targetLines: {
    type: Number,
    required: false,
    default: 4
  }
})

// 定义响应式变量
const expanded = ref(false)  // 控制文本是否展开
const isCollapsible = ref(false)  // 控制文本是否需要折叠
const textContainer = ref(null)  // 引用文本容器
const truncatedText = ref('')  // 存储截断的文本

// 切换展开/收起状态的函数
const toggleExpand = () => {
  expanded.value = !expanded.value
}

// 检查文本是否需要折叠的函数
const checkCollapsible = () => {
  nextTick(() => {
    const width = textContainer.value.clientWidth
    const dummyElement = document.createElement('div')
    dummyElement.style.position = 'absolute'
    dummyElement.style.visibility = 'hidden'
    dummyElement.style.width = `${width}px`
    dummyElement.style.fontSize = props.fontSize  // 设置字体大小
    dummyElement.style.lineHeight = getComputedStyle(textContainer.value).lineHeight
    dummyElement.style.whiteSpace = 'pre-wrap'
    dummyElement.style.wordWrap = 'break-word'
    dummyElement.innerText = props.text
    document.body.appendChild(dummyElement)

    const lineHeight = parseInt(getComputedStyle(dummyElement).lineHeight)  // 获取行高
    const maxHeight = lineHeight * props.targetLines  // 设定最大高度
    isCollapsible.value = dummyElement.clientHeight > maxHeight  // 判断是否需要折叠

    if (isCollapsible.value) {
      // 截断文本以适应最大高度
      let totalHeight = 0
      let truncated = ''
      const words = props.text.split(' ')
      for (let i = 0; i < words.length; i++) {
        const word = words[i]
        dummyElement.innerText = truncated + word + ' ' + '... 展示全部'
        if (dummyElement.clientHeight > maxHeight) break
        truncated += word + ' '
      }
      truncatedText.value = truncated.trimEnd() + '...'
    } else {
      truncatedText.value = props.text
    }

    document.body.removeChild(dummyElement)
  })
}

// 组件挂载时执行的操作
onMounted(() => {
  checkCollapsible()  // 检查文本是否需要折叠
  window.addEventListener('resize', checkCollapsible)  // 监听窗口大小变化,重新检查
})
</script>

<style scoped>

</style>

效果图:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1837253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

没有二十年功力,写不出这一行代码!

这篇文章要从一个奇怪的注释说起&#xff0c;就是下面这张图&#xff1a; 我们可以不用管具体的代码逻辑&#xff0c;只是单单看这个 for 循环。 在循环里面&#xff0c;专门有个变量 j&#xff0c;来记录当前循环次数。 第一次循环以及往后每 1000 次循环之后&#xff0c;进…

阻力支撑相对强度(RSRS)选股系列报告之三

https://download.csdn.net/download/SuiZuoZhuLiu/89447699?spm1001.2014.3001.5503https://download.csdn.net/download/SuiZuoZhuLiu/89447699?spm1001.2014.3001.5503

电脑密码忘记了怎么办?3步教你找回密码!

在日常使用电脑的过程中&#xff0c;忘记密码是一件令人头痛的事情。如果您不慎忘记了电脑的登录密码&#xff0c;无法进入系统进行工作和娱乐&#xff0c;这时需要找到合适的解决方案来恢复对电脑的访问权限。那么电脑密码忘记了怎么办呢&#xff1f;本文将介绍三种解决方法&a…

Uncaught TypeError: Cannot read properties of null (reading ‘isCE‘)

问题描述 使用 view-ui-plus 加 vue3 开发项目&#xff0c;本地启动项目正常&#xff0c;但其他人将代码拉下来&#xff0c;启动项目时报错 Uncaught TypeError: Cannot read properties of null (reading isCE)&#xff1a; 原因分析&#xff1a; 尝试将 mode_nodules 文件删…

C++实时检测耳机的插入与拔出(附源码)

目录 1、实现继承于IMMNotificationClient接口类的CMMNotificationClient类,实时感知音频设备变化的通知事件 2、在CMMNotificationClient的构造函数中初始化多媒体设备COM接口,设置回调类指针 3、通过获取音频设备接口下外设的KSJACK_DESCRIPTION 信息判断耳机的连接状态…

ArcGIS arcpy代码工具——关于工具使用的软件环境说明

系列文章目录 ArcGIS arcpy代码工具——批量对MXD文件的页面布局设置修改 ArcGIS arcpy代码工具——数据驱动工具批量导出MXD文档并同步导出图片 ArcGIS arcpy代码工具——将要素属性表字段及要素截图插入word模板 ArcGIS arcpy代码工具——定制属性表字段输出表格 ArcGIS arc…

鸿蒙实现自定义Tabbar样式,显示数字红点提示

前言&#xff1a; DevEco Studio版本&#xff1a;4.0.0.600 Tabs的链接参考&#xff1a;OpenHarmony Tabs TabContent的链接参考&#xff1a;OpenHarmony TabContent 通过查看链接参考我们知道可以通过TabContent的tabBar来实现自定义TabBar样式&#xff08;CustomBuilder&…

“运动过量”?想多了,普通骑友没那能力和意志力,好好骑车吧

最近听到“运动过量”这个词挺多的&#xff0c;身为骑行爱好者的校长&#xff0c;感觉又好笑又无奈&#xff0c;所以想写点东西&#xff0c;这篇文通过分析普通骑友的运动习惯、能力和意志力&#xff0c;探讨了“运动过量”这一概念在骑行领域中的适用性。文章指出&#xff0c;…

基于PHP的民宿管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的民宿管理系统 一 介绍 此民宿管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端jquery.js和echarts.js。系统角色分为用户和管理员。用户可以在线浏览和预订民宿&#xff0c;管理员登录后台进行相关管理等。(在系统…

精度丢失引起的支付失败问题

问题描述 在提交订单时候&#xff0c;输入充值金额和优惠码&#xff0c;后台会返回具体的订单信息&#xff0c;如下图&#xff0c;支付金额应该是1 * (1 - 0.09) 0.91&#xff08;这个是理想状态&#xff09;&#xff0c;但是表单显示的是0.90999997&#xff0c; 然后点击确…

大模型系列:提示词管理

既然大模型应用的编程范式是面向提示词的编程&#xff0c;需要建立一个全面且结构化的提示词库&#xff0c; 对提示词进行持续优化也是必不可少的&#xff0c;那么如何在大模型应用中更好的管理提示词呢&#xff1f; 1. 提示词回顾 提示词在本质上是向大型语言模型&#xff08;…

算法设计与分析 实验3 回溯法求地图填色问题

目录 一、实验目的 二、背景知识 三、实验内容 四、算法思想 未优化的回溯算法 节点选择-最小剩余值准则&#xff08;MRV&#xff09; 节点选择-最多约束准则&#xff08;DH&#xff09; 颜色选择-最少约束选择 数据结构的选择 向前探查 颜色轮换&#xff08;贪心置…

构建专属Web SSH客户端:从零到一打造你的在线运维利器

随着云服务和远程工作的普及&#xff0c;能够随时随地访问服务器变得越来越重要。虽然市面上已有不少成熟的SSH客户端&#xff0c;但打造一个属于自己的Web版SSH工具&#xff0c;不仅能根据个人需求定制功能&#xff0c;还能享受灵活访问的便利。 本文将带你一步步实践&#xf…

linux——ansible实验

要求 0.进入servera进行准备工作&#xff0c;做一些清理 1&#xff09;停止httpd服务&#xff0c;清除httpd软件包、配置文件、主页文件 2&#xff09;清理/etc/hosts文件中的内容&#xff0c;只保留最上面默认的两行 &#xff08;127.0.0.1和::1这两行&#xff09; 1.根据之前…

004-配置交换机ssh远程登录

配置交换机ssh远程登录 注意事项 要远程的本机电脑必须与该交换机在同一个网段&#xff0c;以下实验在172.16.12段下模拟&#xff0c;本地ip设置为172.16.12.10&#xff0c;交换机的ip设置为172.16.12.254 将密码设置为明文&#xff08;simple&#xff09;是不安全的&#x…

分布式技术导论 — 探索分析从起源到现今的巅峰之旅(消息队列)

探索分析从起源到现今的巅峰之旅 分布式队列 - Kafka架构特性可扩展性磁盘优化与顺序访问大容量存储与历史数据利用高效数据封装与压缩智能内存管理与OS缓存利用 Kafka发布/订阅模型Kafka架构分析Producer和Consumer接口交互Producer通过Topic发送数据Consumer通过Topic消费数据…

【Ubuntu】--- 创建用户 删除用户 及其他用户操作大全 持续更新中

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【Ubuntu】--- 创建用户 删除用户 及其他…

React常用方法汇总【更新中】

文章目录 前言创建项目启动命令列表渲染useEffect 异步函数使用方法useEffect 异步函数清除方法控制组件显示隐藏axios 安装使用 前言 运行 react 需要先安装 node.js&#xff0c;具体安装步骤可以参考这篇文章 https://blog.csdn.net/weixin_43721000/article/details/134284…

C++ 57 之 静态联编和动态联编

#include <iostream> #include <string> using namespace std;// 动态多态产生条件: // 1.要有继承关系 // 2.父类中有虚函数、子类要重写父类的虚函数 // 3.父类的指针或引用指向子类的对象class Animal{ public:virtual void speak(){ // 虚函数 父类中的vir…

大数据—“西游记“全集文本数据挖掘分析实战教程

项目背景介绍 四大名著&#xff0c;又称四大小说&#xff0c;是汉语文学中经典作品。这四部著作历久不衰&#xff0c;其中的故事、场景&#xff0c;已经深深地影响了国人的思想观念、价值取向。四部著作都有很高的艺术水平&#xff0c;细致的刻画和所蕴含的思想都为历代读者所…