React文字展開收起組件的實現(xiàn)示例
前言
最近想把在項目中封裝的一些公用組件奉獻出來,畢竟獨樂樂不如眾樂樂,好東西就要大家分享。這次還是來聊實戰(zhàn),主題就是文字展開收起組件的實現(xiàn)過程,這個需求在前端項目中也算常見的需求了,可能你已經(jīng)在項目中使用了自己或別人封裝的組件,但是這次還是希望你能耐心地看看我的實現(xiàn)過程,畢竟多一個思路也會讓你在后續(xù)的工作中游刃有余。
背景
老規(guī)矩,實戰(zhàn)項目必有背景。那還是先來聊聊這個文字展開收起組件產(chǎn)生的需求背景,需求其實就是要你把多余的文字省略顯示,然后有展開收起的按鈕可以操作。對,就是這么直白,上圖:
上圖是文字收起的圖示,超過一定的字數(shù)那就收起省略顯示,并出現(xiàn)查看全部
按鈕。
上圖顯示的就是操作了查看全部
按鈕之后,文字需要全部顯示出來并有收起
按鈕。還是來看一張gif圖的顯示最后該組件完成后的效果,如下圖:
開發(fā)
該組件還是使用React+typescript
的技術(shù)棧,所以還是之前的老話,如果不是此技術(shù)棧的同學(xué)就只有參考實現(xiàn)思路,后續(xù)待不忙時再來提供其他技術(shù)棧對應(yīng)的版本。
文字展開收起組件的開發(fā)就沒有啥思考的點,就只需要在做的時候考慮一定字數(shù)
這個問題,超過它截取文字并加上...
,然后展開時展示所有文字即可,其它的操作基本是常規(guī)操作。話不多說,直接往下看→
1.1 定義組件所需字段
interface IndexProps { content: string; // 文本內(nèi)容 maxLen?: number; // 文字最大顯示長度 expandText?: string; // 展開按鈕文字 collapseText?: string; // 收起按鈕文字 contentRender: (text: string, handler: React.ReactNode) => React.ReactNode; // 自定義內(nèi)容 onExpand?: (expanded: boolean) => void; // 展開、收起后觸發(fā) }
可以看到文字展開收起組件需要用到上述6
個字段,其中content
,contentRender
是必須傳入的,否則組件會報錯,其他字段皆為可選字段,需要時就傳入不需要就會使用組件定義的默認值。
1.2 獲取截斷后的文字
獲取截斷后的文字,其實是根據(jù)字段maxLen
來自動獲取,maxLen
設(shè)置的默認值為300
,即超過300
個文字之后就會被截斷。maxLen
的值是可以修改的,若你設(shè)置為200
,即文字超過200
就會被截取,故其為可選字段。代碼如下:
/** * 獲取截斷后的文字 * @param text */ const getText = (text: string): string => { return (text || '').slice(0, maxLen) + '...' }
1.3 獲取展開收起按鈕
細心的小伙伴可以從1.1
定義的字段中可以看到,其中contentRender
這個字段代表的意思為自定義內(nèi)容,即該組件的內(nèi)容是可以自定義的。因為在設(shè)計的時候,就考慮到該組件應(yīng)用的場景可能有點多,所以希望它是可以根據(jù)不同的需求場景來進行自定義的,所以該組件的render
內(nèi)容就只有此方法,如下:
return ( <>{contentRender(body, getExpandBtn())}</> )
contentRender
方法其實接收兩個參數(shù):text
代表文本內(nèi)容,其實就是傳入的content
,只不過它會根據(jù)判斷條件判斷是否被截??;在組件加載時,就會對其進行如下判斷:
useEffect(() => { let contentBody = content || ''; if (contentBody.length > maxLen) { contentBody = getText(contentBody); setShowBtn(true); } setBody(contentBody); return () => { setExpanded(false); setShowBtn(false); } }, [content]);
通過上述代碼可以獲取到需要渲染的文本內(nèi)容,然后將其賦值給body
,即它就是contentRender
方法接收的第一個參數(shù)。
而第二個參數(shù)handler
其實就是這里將要說的,獲取展開收起按鈕的方法。如下:
/** * 獲取展開收起按鈕 * @param status */ const getExpandBtn = (): React.ReactNode => ( showBtn ? ( <span className="custom-text-expanded-handler" onClick={() => expandToggle(!expanded)} >{expanded ? collapseText : expandText} </span> ) : null )
從上可以看到,所謂的自定義其實就是我們可以對參數(shù)text
進行自定義,可以將其使用div
包裹,或者對其樣式進行自定義皆是可以的。而在我們的項目中,則是又寫一個名詞解釋組件
對其自定義,名詞解釋組件
可在下篇文章中簡述。
1.4 展開收起邏輯
所謂的展開收起邏輯其實就是讓文字省略展示或者全部展示,而在這個過程中可以使用暴露出去的onExpand
方法做其他邏輯操作,代碼如下:
/** * 展開、收起 * @param status */ const expandToggle = (status: boolean) => { let text = status ? content : getText(content); setExpanded(status); setBody(text); onExpand(status); }
1.5 完整代碼
好了,通過上述的簡單介紹,組合代碼可以得到文字展開收起組件完整代碼。
1.5.1 邏輯代碼
創(chuàng)建index.tsx
文件,并寫入如下所示代碼:
import * as React from 'react'; import {useEffect, useState} from "react"; import './index.scss'; interface IndexProps { content: string; // 文本內(nèi)容 maxLen?: number; // 文字最大顯示長度 expandText?: string; // 展開按鈕文字 collapseText?: string; // 收起按鈕文字 contentRender: (text: string, handler: React.ReactNode) => React.ReactNode; // 自定義內(nèi)容 onExpand?: (expanded: boolean) => void; // 展開、收起后觸發(fā) } /** * 自定義文字展開收起組件 * @param props * @constructor */ const TextExpand = (props: IndexProps) => { const { content, maxLen = 300, expandText = '查看全部', collapseText = '收起', contentRender = (text: string, handler: React.ReactNode) => {}, onExpand = (expanded: boolean) => {}, } = props; const [body, setBody] = useState<any>(null); const [expanded, setExpanded] = useState<boolean>(false); const [showBtn, setShowBtn] = useState<boolean>(false); useEffect(() => { let contentBody = content || ''; if (contentBody.length > maxLen) { contentBody = getText(contentBody); setShowBtn(true); } setBody(contentBody); return () => { setExpanded(false); setShowBtn(false); } }, [content]) /** * 獲取截斷后的文字 * @param text */ const getText = (text: string): string => { return (text || '').slice(0, maxLen) + '...' } /** * 獲取展開收起按鈕 * @param status */ const getExpandBtn = (): React.ReactNode => ( showBtn ? ( <span className="custom-text-expanded-handler" onClick={() => expandToggle(!expanded)} >{expanded ? collapseText : expandText} </span> ) : null ) /** * 展開、收起 * @param status */ const expandToggle = (status: boolean) => { let text = status ? content : getText(content); setExpanded(status); setBody(text); onExpand(status); } return ( <>{contentRender(body, getExpandBtn())}</> ) } export default TextExpand;
1.5.2 樣式代碼
創(chuàng)建index.scss
文件,同樣寫入如下代碼即可:
.custom-text-expanded-handler { margin-left: 6px; color: #545FD6; &:hover { color: #1890ff; cursor: pointer; } }
1.6 安裝使用組件
組件寫好,那就來使用它。該組件已經(jīng)發(fā)布到npm
上了,所以小伙伴們可以到npm
上查看并下載,也可以通過如下命令進行安裝使用:
npm i react-text-expand-collapse 或 yarn add react-text-expand-collapse
安裝好之后,在項目中引用使用:
// 引入組件 import TextExpand from 'react-text-expand-collapse/src/index'; // 使用 <div style={{ width: 500, margin: '10px auto 0', color: '#333', fontSize: '12px', textAlign: 'left', backgroundColor: '#fff' }}> <TextExpand content={str} maxLen={100} contentRender={(text: string, handler: any) => { return ( <> <span>{text}</span> {handler} </> ) }} /> </div>
最后實現(xiàn)效果,如下圖:
如果你有需求需要用到該組件但不想去下載安裝,那你就直接把這個完整代碼拷到你的項目中去,直接創(chuàng)建文件引用即可。(最好還是下載使用吧,這樣對作者有一定的支持,作者也會挺開心的^_^)
最后,文字展開收起組件的開發(fā)思路和實現(xiàn)就介紹完了,其實這個需求還是挺常見的,如果你以后遇到這樣的需求就來看看我的這篇文章吧,3Q??
資源
npm地址:react-text-expand-collapse
github倉庫:https://github.com/Jacky010/react-text-expandCollapse
到此這篇關(guān)于React文字展開收起組件的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)React文字展開收起內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react?表單數(shù)據(jù)形式配置化設(shè)計
這篇文章主要介紹了react表單數(shù)據(jù)形式配置化設(shè)計,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-07-07React Native使用Modal自定義分享界面的示例代碼
本篇文章主要介紹了React Native使用Modal自定義分享界面的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10