淺析react里面如何封裝一個(gè)通用的Ellipsis組件
背景
在平時(shí)的業(yè)務(wù)場景中,為了提升用戶體驗(yàn),經(jīng)常會(huì)使用固定寬度,超出顯示...的css樣式。但是每次都寫一次,比較麻煩,為了更好的摸魚,所以把Ellipsis組件抽離出來。
先捋一下要實(shí)現(xiàn)的功能:
- 固定寬度,超出顯示...
- 鼠標(biāo)
hover上去,能看到全部 - 支持多行顯示...
- 考慮
resize場景
思路
計(jì)算要渲染文字的寬度,如果寬度超出,就顯示...
這里的問題是,如何計(jì)算文字的寬度呢?
- 可以先把文字在看不見的地方先渲染出來,獲取到實(shí)際寬度,然后再去比較
- 直接給容器設(shè)置
overflow:hidden,然后比較scrollWidth跟clientWidth的值
這里我用的是第二種。
import React, { FC, useCallback, useLayoutEffect, useRef, useState } from 'react';
import { Tooltip } from 'antd';
import debounce from 'lodash/debounce';
import useDimensions from 'react-cool-dimensions';
import { TooltipProps } from 'antd/lib';
interface EllipsisProps {
line?: number
style?: React.CSSProperties
children?: React.ReactElement
}
const Ellipsis: FC<EllipsisProps & TooltipProps> = (props) => {
const {
children,
line = 1,
style: currentStyle = {},
...other
} = props;
const wrapper = useRef<HTMLElement>();
const [showPopover, setShowPopover] = useState(false);
// 先設(shè)置overflow: 'hidden', 這樣超出了才能進(jìn)行比較
const defaultStyle: React.CSSProperties = line === 1 ? {
display: 'block',
maxWidth: '100%',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
...currentStyle
} : {
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: line,
...currentStyle
}
const validShowPopover = () => {
// 當(dāng)line為1的時(shí)候,比較width
// 否則,比較height
const {
scrollWidth = 0,
clientWidth = 0,
scrollHeight = 0,
clientHeight = 0
} = wrapper.current as HTMLElement || {};
setShowPopover(scrollWidth > clientWidth || scrollHeight > clientHeight)
}
const debounceMesaure = useCallback(debounce(() => {
validShowPopover();
}, 200), [validShowPopover]);
// 支持resize
const { observe } = useDimensions({
onResize: debounceMesaure,
});
useEffect(() => {
validShowPopover();
}, []);
const renderChildren = () => {
return React.cloneElement(children, {
style: defaultStyle,
ref: (element: HTMLElement | undefined) => {
observe(element);
wrapper.current = element;
},
})
}
// 基于ant的Tooltip組件
if (showPopover) {
return <Tooltip {...other}>{renderChildren()}</Tooltip>
}
return renderChildren();
}
export default Ellipsis
使用
Ellipsis組件的children必須是一個(gè)html元素標(biāo)簽
如果要渲染的元素沒有給定寬度的話,需要手動(dòng)向Ellipsis組件傳一個(gè)width參數(shù)
import Ellipsis from './Ellipsis';
const EllipsisPage = () => {
return <div>
<Ellipsis style={{ width: 200 }} title={text} line={2}>
<span>{text}</span>
</Ellipsis>
</div>
}
export default EllipsisPage;
如果要渲染的元素已經(jīng)有指定的寬度,則不需要
import Ellipsis from './Ellipsis';
const EllipsisPage = () => {
return <div>
<div style={{ width: 200 }}>
<Ellipsis title={text} line={1}>
<span>{text}</span>
</Ellipsis>
</div>
</div>
}
export default EllipsisPage;
到此這篇關(guān)于淺析react里面如何封裝一個(gè)通用的Ellipsis組件的文章就介紹到這了,更多相關(guān)react封裝Ellipsis組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決React報(bào)錯(cuò)Property 'X' does not 
這篇文章主要為大家介紹了解決React報(bào)錯(cuò)Property 'X' does not exist on type 'HTMLElement',有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
React Native 搭建開發(fā)環(huán)境的方法步驟
本篇文章主要介紹了React Native 搭建開發(fā)環(huán)境的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
JavaScript中rem布局在react中的應(yīng)用
這篇文章主要介紹了JavaScript中rem布局在react中的應(yīng)用 的相關(guān)資料,需要的朋友可以參考下2015-12-12
React中進(jìn)行條件渲染的實(shí)現(xiàn)方法
React是一種流行的JavaScript庫,它被廣泛應(yīng)用于構(gòu)建Web應(yīng)用程序,在React中,條件渲染是一個(gè)非常重要的概念,它允許我們根據(jù)不同的條件來呈現(xiàn)不同的內(nèi)容,在本文中,我們將探討React如何進(jìn)行條件渲染,需要的朋友可以參考下2023-11-11
React State狀態(tài)與生命周期的實(shí)現(xiàn)方法
這篇文章主要介紹了React State狀態(tài)與生命周期的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
ReactNative實(shí)現(xiàn)Toast的示例
這篇文章主要介紹了ReactNative實(shí)現(xiàn)Toast的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12

