目标-小程序端:
- 最多两行,超出使用省略号
- 在省略号后面加入其他文案
- 尾部加入的文案可以点击
- 文字过少时单行不需要省略号和其他文案
-
效果图如下
思路
单纯的css可以勉强实现这个效果,但是无法判断文字是否溢出,小程序端要获取dom信息很麻烦,得用异步的方法并且还和html的dom不一样
所以最后改成了用js手动判断,固定一行8个字,这样就能判断是否溢出了,然后使用字符串截取等方法分组渲染
先实现一个分组方法,给字符串每8个字一组分组
export function chunk(str, groupLength) {
if (typeof str !== 'string') {
return []
}
// 利用Array.from创建指定长度的数组,并映射为字符串片段
return Array.from({ length: Math.ceil(str.length / groupLength) },
(_, i) => str.slice(i * groupLength, (i + 1) * groupLength)
);
}
然后截取分好的数组的前2组
import { View, Text } from '@tarojs/components';
import classNames from 'classnames';
import type React from 'react';
import { chunk } from '@/utils/common';
import styles from './index.module.scss';
interface EllipsisRowProps {
content: string; //字符串内容
rowLen: number; // 一行最多承载的字符数
colLen: number; // 最多xx行
className?: string;
moreText?: string; // 尾部的文字
onMoreClick?: () => void; // 尾部的文字点击
}
const EllipsisRow: React.FC<EllipsisRowProps> = ({ content, rowLen = 8, colLen = 2, className, moreText = '全部', onMoreClick }) => {
if (!content) {
return null;
}
// 8个字符为一组, 截取前2组
const originLines = chunk(content, rowLen);
const lines = originLines.slice(0, colLen);
// 判断是否溢出
const isOverflow = originLines.length > lines.length;
return (
<View className={classNames(styles.wrapper, className)}>
{lines.map((lineStr, index) => {
// 最后一行并且是溢出的情况
if (index === lines.length - 1 && isOverflow) {
return (
<View key={lineStr}>
{lineStr.slice(0, 5)}...
<Text className={styles.more} onClick={onMoreClick}>
{moreText}
</Text>
</View>
);
}
return <View key={lineStr}>{lineStr}</View>;
})}
</View>
);
};
export default EllipsisRow;