今天我們講講項(xiàng)目中實(shí)戰(zhàn)就是文字展開收起組件的實(shí)現(xiàn)過程,講解這個(gè)就是為了讓多給大家一個(gè)思路,想法。
簡單來說文字展開收起組件產(chǎn)生的需求背景,就是為省略顯示,然后有展開收起的按鈕可以操作。我們看顯示效果上圖:
上圖是文字收起的圖示,超過一定的字?jǐn)?shù)那就收起省略顯示,并出現(xiàn)查看全部按鈕。
上圖顯示的就是操作了查看全部按鈕之后,文字需要全部顯示出來并有收起按鈕。還是來看一張gif圖的顯示最后該組件完成后的效果,如下圖:
開發(fā)
該組件繼續(xù)使用React+typescript的技術(shù)棧,要是沒有使用此技術(shù)棧的同學(xué)就只有參考實(shí)現(xiàn)思路,后續(xù)待不忙時(shí)再來提供其他技術(shù)棧對應(yīng)的版本。
文字展開收起組件開發(fā),我們現(xiàn)在就只需要在做的時(shí)候考慮一定字?jǐn)?shù)這個(gè)問題,超過它截取文字并加上...,然后展開時(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ā) }
運(yùn)行之后我們就可以看到文字展開收起組件,其中content,contentRender是必須傳入的,否則組件會(huì)報(bào)錯(cuò),其他字段皆為可選字段,在要用到的時(shí)候就會(huì)傳入,不用就使用組件定義的默認(rèn)值。
1.2 獲取截?cái)嗪蟮奈淖?/p>
獲取截?cái)嗪蟮奈淖?,其?shí)是根據(jù)字段maxLen來自動(dòng)獲取,maxLen設(shè)置的默認(rèn)值為300,即超過300個(gè)文字之后就會(huì)被截?cái)?。maxLen的值是可以修改的,若你設(shè)置為200,即文字超過200就會(huì)被截取,故其為可選字段。代碼如下:
/** * 獲取截?cái)嗪蟮奈淖? * @param text */ const getText = (text: string): string => { return (text || '').slice(0, maxLen) + '...' }
1.3 獲取展開收起按鈕
不小人是不是從1.1定義的字段中可以看到,其中contentRender這個(gè)字段代表的意思為自定義內(nèi)容,即該組件的內(nèi)容是可以自定義的。講白了說就是在設(shè)計(jì)的時(shí)候,就已經(jīng)想到組件應(yīng)用的場景在有點(diǎn)多的情況下,也可以讓它是可以根據(jù)不同的需求場景來進(jìn)行自定義的,所以該組件的render內(nèi)容就只有此方法,如下:
return ( <>{contentRender(body, getExpandBtn())}</> )
contentRender方法其實(shí)接收兩個(gè)參數(shù):text代表文本內(nèi)容,其實(shí)就是傳入的content,只不過它會(huì)根據(jù)判斷條件判斷是否被截??;在組件加載時(shí),就會(huì)對其進(jìn)行如下判斷:
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方法接收的第一個(gè)參數(shù)。
而第二個(gè)參數(shù)handler其實(shí)就是這里將要說的,獲取展開收起按鈕的方法。如下:
/** * 獲取展開收起按鈕 * @param status */ const getExpandBtn = (): React.ReactNode => ( showBtn ? ( <span className="custom-text-expanded-handler" onClick={() => expandToggle(!expanded)} >{expanded ? collapseText : expandText} </span> ) : null )
從上可以看到,所謂的自定義其實(shí)就是我們可以對參數(shù)text進(jìn)行自定義,可以將其使用div包裹,或者對其樣式進(jìn)行自定義皆是可以的。而在我們的項(xiàng)目中,則是又寫一個(gè)名詞解釋組件對其自定義,名詞解釋組件可在下篇文章中簡述。
1.4 展開收起邏輯
所謂的展開收起邏輯其實(shí)就是讓文字省略展示或者全部展示,而在這個(gè)過程中可以使用暴露出去的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]) /** * 獲取截?cái)嗪蟮奈淖? * @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上查看并下載,也可以通過如下命令進(jìn)行安裝使用:
1
npm i react-text-expand-collapse 或 yarn add react-text-expand-collapse
安裝好之后,在項(xiàng)目中引用使用:
// 引入組件 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>
最后實(shí)現(xiàn)效果,如下圖:
文章內(nèi)的代碼有需要也可以直接拷走使用,也可以應(yīng)用在項(xiàng)目中,幫助大家解決問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/127976.html
摘要:傳給回調(diào)函數(shù)的里,包含一個(gè)觸摸事件參數(shù)。官網(wǎng)的版文檔中,和組件中都有屬性,這個(gè)屬性接收一個(gè)回調(diào)函數(shù),函數(shù)原型是,在組件和的組件的時(shí)候觸發(fā)該事件,傳給回調(diào)函數(shù)的里,參數(shù),其中的屬性為該組件的。 1、問題 問題場景: 由于手機(jī)屏幕高度不定,做表單頁面時(shí),外層通常加上ScrollView組件,使其能夠適應(yīng)屏幕進(jìn)行滾動(dòng)。業(yè)務(wù)需要里面放置多個(gè)TextInput組件。 問題描述: 出現(xiàn)的問題是,首...
摘要:自從年月份對外公布以來,已經(jīng)經(jīng)過了個(gè)月的迭代,期間發(fā)布了幾十個(gè)正式版本,但一直沒有到,因?yàn)槲覀冇X得是個(gè)里程碑版本,我們必須做的足夠完善才敢稱之為。 自從17年11月份對外公布以來,KPC已經(jīng)經(jīng)過了8個(gè)月的迭代,期間發(fā)布了幾十個(gè)正式版本,但一直沒有到1.0,因?yàn)槲覀冇X得1.0是個(gè)里程碑版本,我們必須做的足夠完善才敢稱之為1.0。而如今我們有信心對外宣布:KPC 1.0終于來了! 其實(shí)距離...
摘要:寫在前面的嘮簡單記錄一下工作中出現(xiàn)的需求和常見的問題,時(shí)常記錄總結(jié),希望能在之后的工作中吸取經(jīng)驗(yàn)教訓(xùn),提高工作效率。只展示一行數(shù)據(jù)的時(shí)候給固定高度為了顯示展開收起按鈕,因?yàn)樵O(shè)定分辨率是來回變的,思來想去還是使用了監(jiān)聽事件。 寫在前面的嘮 簡單記錄一下工作中出現(xiàn)的需求和常見的問題,時(shí)常記錄總結(jié),希望能在之后的工作中吸取經(jīng)驗(yàn)教訓(xùn),提高工作效率。如果可以幫助有同樣問題的同學(xué)我會(huì)很開心的,有的...
摘要:然后使用,在的上綁定了,很簡單。日歷遍歷的思路這一次的提交主要是確定了日歷組件,怎么寫,具體思路看下面的代碼,盡量通過注釋把思路講的清楚一些。前言 在最近的項(xiàng)目中,大量的嘗試了react hooks,我們的組件庫用的是Next,除了一個(gè)地方因?yàn)橐褂肍orm + Field的組合,所以使用了class組件,經(jīng)過了這個(gè)項(xiàng)目,也算是總結(jié)一些使用的經(jīng)驗(yàn),所以準(zhǔn)備自己封裝一個(gè)日歷組件來分享一下。以下...
閱讀 561·2023-03-27 18:33
閱讀 750·2023-03-26 17:27
閱讀 647·2023-03-26 17:14
閱讀 603·2023-03-17 21:13
閱讀 537·2023-03-17 08:28
閱讀 1823·2023-02-27 22:32
閱讀 1315·2023-02-27 22:27
閱讀 2199·2023-01-20 08:28