因为需求,原生写了一遍,通过其他人的建议,重新用的组件写了一遍。效果如下:
原生的方法:
遇到的难点:
- 如何根据文本的多少,控制是否显示省略号和展开按钮。 解决: 根据动态判断该dom元素的高度,是否显示展开按钮和省略号。 用到技术:hooks;
const [truncated, setTruncated] = useState(false); // 是否显示展开按钮;
useLayoutEffect(() => {
// 获取dom元素
if (contentRef.current?.offsetHeight) {
const content = contentRef.current;
if (content?.scrollHeight > content?.offsetHeight) {
setTruncated(true);
} else if (content?.scrollHeight < content?.offsetHeight) {
setTruncated(false);
}
}
});
- 展开^ 或 收起v,如果控制一直在文本的最后。 解决:
- 通过点击的显示隐藏开关去控制是否显示那个按钮。
- 通过css实现:伪类实现:
控制按钮的开关,给后面的span添加动态的伪类。
&::after {
content: '展开 v';
};
or
&::after {
content: '收起 ^';
};
组件的方法:
遇到的难点:
- 如何根据文本的多少,控制是否显示省略号和展开按钮。 解决:
import { Typography } from 'antc';
const { Paragraph } = Typography;
// 是否展示展开/收起的按钮。
const [showEllipsis, setShowEllipsis] = useState(false);
const [visible, setVisible] = useState(false);
// 判断是否显示省略号
const handleEllipsis = (ellipsis: any) => {
if (ellipsis) {
setShowEllipsis(true);
}
};
<Paragraph
ellipsis={
visible
? false
: {
rows: 2,
expandable: true,
symbol: (
<a style={{ visibility: 'hidden' }}
onClick={() => setVisible(true)} // 不生效
>
<DownOutlined />
展开
</a>
), // 为什么 hidden,因为设置了 expandable: true,可展开,但是这里设置setVisible(true),不生效。
onEllipsis: (ellipsis) => handleEllipsis(ellipsis),
}
}
>
{detail?.materialTaskContent}
{visible && (
<a
onClick={() => {
setVisible(false);
}}
>
<UpOutlined />
收起
</a>
)}
</Paragraph>
{showEllipsis && !visible && (
<div style={{ position: 'absolute', bottom: 0, right: 0 }}>
<a onClick={() => setVisible(true)}>
<DownOutlined />
展开
</a>
</div>
)}
最后还是感觉组件好用,只要认真耐心看作用就会很方便。 (#^.^#)