呦!大家好,好久没有更新博客了,最近实现了一个一直想自己完成的一个东西,就是文本的展开收起组件,以前项目需要用到,自己实现一个又太繁琐,所以那个时候都是用的别人的轮子,现在自己尝试了一下,居然实现了,所以在这里向各位分享一下。(郑重声明,实现肯定有很多种方法,下面的只是我自己原创的方法,不喜勿喷)代码其实很简单,夸张一点说,我感觉应该是目前能找到的最简单的实现方式了,注释也很详细,具体的实现效果也还是不错的,现在在下面贴一下代码:
npm包的链接在这里:text-clamp-for-vue3 - npm (npmjs.com)
展示:
TextClamp.vue
<script setup lang="ts">
import { addListener, removeListener } from 'resize-detector'
import { ref, onMounted, onUnmounted } from 'vue'
import $ from 'jquery'
const props = withDefaults(defineProps<{
text: string; // 传入的文本,必传项
buttonType?: 'oneLine' | 'tight'; // 展开收起按钮分为:1. oneLine:自身占据单行 2. tight:和文字紧密相邻
maxLines?: number; // 设置的显示的行数
isExpanded?: boolean; // 展开的状态,true:展开,false:收起
}>(), {
buttonType: 'oneLine',
isExpanded: false,
maxLines: 3
})
const textClampRef = ref<HTMLElement | null>(null) // 最外层div的ref
const textRef = ref<HTMLElement | null>(null) // 该组件放文本内容的ref
const toggleButtonRef = ref<HTMLElement | null>(null)
const expanded = ref(props.isExpanded) //本地的expanded状态,先获取一遍属性中的isExpanded状态,然后才能用toggle方法进行修改
const offset = ref(0) // 这个是文本的截取位置,初始从0开始截取
// 这个是按钮为单行的模式下的折叠文本的css
const clampClass = ref({
'display': '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': `${props.maxLines}`,// 这里可以根据给定的行数设置具体的clamp行数,这也是我要将css封装成一个对象的目的
'overflow': 'hidden',
'text-overflow': 'ellipsis'
})
/**
* 将文本截取标志offset往右移动一个单位,同时截取文本并赋值
*/
function moveOffsetRight() {
offset.value = offset.value + 1
textRef.value && (textRef.value.textContent = props.text.slice(0, offset.value) + '...')
}
/**
* 将文本截取标志offset往左移动一个单位