淺析react里面如何封裝一個(gè)通用的Ellipsis組件
背景
在平時(shí)的業(yè)務(wù)場(chǎng)景中,為了提升用戶(hù)體驗(yàn),經(jīng)常會(huì)使用固定寬度,超出顯示...的css樣式。但是每次都寫(xiě)一次,比較麻煩,為了更好的摸魚(yú),所以把Ellipsis組件抽離出來(lái)。
先捋一下要實(shí)現(xiàn)的功能:
- 固定寬度,超出顯示...
- 鼠標(biāo)
hover
上去,能看到全部 - 支持多行顯示...
- 考慮
resize
場(chǎng)景
思路
計(jì)算要渲染文字的寬度,如果寬度超出,就顯示...
這里的問(wèn)題是,如何計(jì)算文字的寬度呢?
- 可以先把文字在看不見(jiàn)的地方先渲染出來(lái),獲取到實(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)簽
如果要渲染的元素沒(méi)有給定寬度的話,需要手動(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)容請(qǐng)搜索腳本之家以前的文章或繼續(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-12React Native 搭建開(kāi)發(fā)環(huán)境的方法步驟
本篇文章主要介紹了React Native 搭建開(kāi)發(fā)環(huán)境的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10JavaScript中rem布局在react中的應(yīng)用
這篇文章主要介紹了JavaScript中rem布局在react中的應(yīng)用 的相關(guān)資料,需要的朋友可以參考下2015-12-12React中進(jìn)行條件渲染的實(shí)現(xiàn)方法
React是一種流行的JavaScript庫(kù),它被廣泛應(yīng)用于構(gòu)建Web應(yīng)用程序,在React中,條件渲染是一個(gè)非常重要的概念,它允許我們根據(jù)不同的條件來(lái)呈現(xiàn)不同的內(nèi)容,在本文中,我們將探討React如何進(jìn)行條件渲染,需要的朋友可以參考下2023-11-11React State狀態(tài)與生命周期的實(shí)現(xiàn)方法
這篇文章主要介紹了React State狀態(tài)與生命周期的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03ReactNative實(shí)現(xiàn)Toast的示例
這篇文章主要介紹了ReactNative實(shí)現(xiàn)Toast的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12