备注:
- 使用
TypeScript
和React
的函数式组件语法。此组件的目的是显示文本,如果文本内容超出了指定的行数,它将显示一个“查看更多
”的按钮。- 当用户点击这个按钮时,将展示全部的文本内容。组件使用了自定义的钩子
useBoundingClientRect
来确定是否需要显示这个按钮
//index.tsx文件
import type { FC, JSX } from 'react';
import { Fragment, useState } from 'react';
import type { StandardProps } from '@tarojs/components';
import { Image, Text, View } from '@tarojs/components';
import iconDropDown from '@/assets/icons/icon-dorpdown-primary.svg';
import useBoundingClientRect from '@/hooks/useBoundingClientRect';
import './index.less';
interface EllipsisProps {
rows?: number;
/**
* 收起节点
*/
foldRender?: JSX.Element;
/**
* 是否显示收取按钮
*/
showFold?: boolean;
/**
* 展开节点
*/
unfoldRender?: JSX.Element;
/**
* 是否显示展开按钮
*/
showUnfold?: boolean;
onChange?: (val: boolean) => void;
}
const Ellipsis: FC<EllipsisProps & StandardProps> = ({
rows = 1,
children,
className,
showUnfold,
unfoldRender,
}) => {
const [show, setShow] = useState(false);
const [rectAssist] = useBoundingClientRect('#rectAssist', [children]);
const [rectActual] = useBoundingClientRect('#rectActual', [children]);
const style = {
lineClamp: rows,
webkitLineClamp: rows,
};
const showMoreBtn =
!show &&
showUnfold &&
rectActual?.height &&
rectAssist?.height &&
Number(rectActual?.height) !== Number(rectAssist?.height);
return (
<Fragment>
<View
style={{ position: 'absolute', left: 0, top: -999999, opacity: 0 }}
className={className}
id="rectAssist"
>
{children}
</View>
<View
className={`lineClamp__1 ${className}`}
style={!show ? style : { display: 'block' }}
id="rectActual"
>
{children}
{!!showMoreBtn && (
<View className="unfold-wrap" id="unfoldWrap" onClick={() => setShow(true)}>
{unfoldRender || (
<View className="unfold-btn">
<Text>查看更多</Text>
<Image src={iconDropDown} />
</View>
)}
</View>
)}
</View>
</Fragment>
);
};
export default Ellipsis;
css样式index.less
.lineClamp(@row) {
display: -webkit-box;
overflow: hidden;
line-clamp: @row;
-webkit-line-clamp: @row;
-webkit-box-orient: vertical;
position: relative;
}
.lineClamp__1 {
.lineClamp(1);
&::after {
color: red;
position: absolute;
right: 0;
bottom: 5px;
}
}
.lineClamp__2 {
.lineClamp(2);
}
.lineClamp__3 {
.lineClamp(3);
}
.unfold-wrap {
position: absolute;
right: 0;
bottom: 0;
display: flex;
background: linear-gradient(to left, #fff, #fff, #fff, rgba(255, 255, 255, 0.4));
}
.unfold-btn {
display: flex;
flex-direction: row;
align-items: center;
min-width: 32px;
padding: 4px 10px 4px 30px;
line-height: 1;
text {
color: #b89962;
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 12px; /* 100% */
}
image {
width: 13px;
height: 12px;
}
}
使用组件
<View>
<Ellipsis className={styles.name}>{'未知文字文字文字'}</Ellipsis>
</View>