今天我們講講項目中實戰就是文字展開收起組件的實現過程,講解這個就是為了讓多給大家一個思路,想法。
簡單來說文字展開收起組件產生的需求背景,就是為省略顯示,然后有展開收起的按鈕可以操作。我們看顯示效果上圖:
上圖是文字收起的圖示,超過一定的字數那就收起省略顯示,并出現查看全部按鈕。
上圖顯示的就是操作了查看全部按鈕之后,文字需要全部顯示出來并有收起按鈕。還是來看一張gif圖的顯示最后該組件完成后的效果,如下圖:
開發
該組件繼續使用React+typescript的技術棧,要是沒有使用此技術棧的同學就只有參考實現思路,后續待不忙時再來提供其他技術棧對應的版本。
文字展開收起組件開發,我們現在就只需要在做的時候考慮一定字數這個問題,超過它截取文字并加上...,然后展開時展示所有文字即可,其它的操作基本是常規操作。我們一起往下看
1.1 定義組件所需字段
interface IndexProps { content: string; // 文本內容 maxLen?: number; // 文字最大顯示長度 expandText?: string; // 展開按鈕文字 collapseText?: string; // 收起按鈕文字 contentRender: (text: string, handler: React.ReactNode) => React.ReactNode; // 自定義內容 onExpand?: (expanded: boolean) => void; // 展開、收起后觸發 }
運行之后我們就可以看到文字展開收起組件,其中content,contentRender是必須傳入的,否則組件會報錯,其他字段皆為可選字段,在要用到的時候就會傳入,不用就使用組件定義的默認值。
1.2 獲取截斷后的文字
獲取截斷后的文字,其實是根據字段maxLen來自動獲取,maxLen設置的默認值為300,即超過300個文字之后就會被截斷。maxLen的值是可以修改的,若你設置為200,即文字超過200就會被截取,故其為可選字段。代碼如下:
/** * 獲取截斷后的文字 * @param text */ const getText = (text: string): string => { return (text || '').slice(0, maxLen) + '...' }
1.3 獲取展開收起按鈕
不小人是不是從1.1定義的字段中可以看到,其中contentRender這個字段代表的意思為自定義內容,即該組件的內容是可以自定義的。講白了說就是在設計的時候,就已經想到組件應用的場景在有點多的情況下,也可以讓它是可以根據不同的需求場景來進行自定義的,所以該組件的render內容就只有此方法,如下:
return ( <>{contentRender(body, getExpandBtn())}</> )
contentRender方法其實接收兩個參數:text代表文本內容,其實就是傳入的content,只不過它會根據判斷條件判斷是否被截取;在組件加載時,就會對其進行如下判斷:
useEffect(() => { let contentBody = content || ''; if (contentBody.length > maxLen) { contentBody = getText(contentBody); setShowBtn(true); } setBody(contentBody); return () => { setExpanded(false); setShowBtn(false); } }, [content]);
通過上述代碼可以獲取到需要渲染的文本內容,然后將其賦值給body,即它就是contentRender方法接收的第一個參數。
而第二個參數handler其實就是這里將要說的,獲取展開收起按鈕的方法。如下:
/** * 獲取展開收起按鈕 * @param status */ const getExpandBtn = (): React.ReactNode => ( showBtn ? ( <span className="custom-text-expanded-handler" onClick={() => expandToggle(!expanded)} >{expanded ? collapseText : expandText} </span> ) : null )
從上可以看到,所謂的自定義其實就是我們可以對參數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 邏輯代碼
創建index.tsx文件,并寫入如下所示代碼:
import * as React from 'react'; import {useEffect, useState} from "react"; import './index.scss'; interface IndexProps { content: string; // 文本內容 maxLen?: number; // 文字最大顯示長度 expandText?: string; // 展開按鈕文字 collapseText?: string; // 收起按鈕文字 contentRender: (text: string, handler: React.ReactNode) => React.ReactNode; // 自定義內容 onExpand?: (expanded: boolean) => void; // 展開、收起后觸發 } /** * 自定義文字展開收起組件 * @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 樣式代碼
創建index.scss文件,同樣寫入如下代碼即可:
.custom-text-expanded-handler { margin-left: 6px; color: #545FD6; &:hover { color: #1890ff; cursor: pointer; } }
1.6 安裝使用組件
組件寫好,那就來使用它。該組件已經發布到npm上了,所以小伙伴們可以到npm上查看并下載,也可以通過如下命令進行安裝使用:
1
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>
最后實現效果,如下圖:
文章內的代碼有需要也可以直接拷走使用,也可以應用在項目中,幫助大家解決問題。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127976.html
摘要:傳給回調函數的里,包含一個觸摸事件參數。官網的版文檔中,和組件中都有屬性,這個屬性接收一個回調函數,函數原型是,在組件和的組件的時候觸發該事件,傳給回調函數的里,參數,其中的屬性為該組件的。 1、問題 問題場景: 由于手機屏幕高度不定,做表單頁面時,外層通常加上ScrollView組件,使其能夠適應屏幕進行滾動。業務需要里面放置多個TextInput組件。 問題描述: 出現的問題是,首...
摘要:自從年月份對外公布以來,已經經過了個月的迭代,期間發布了幾十個正式版本,但一直沒有到,因為我們覺得是個里程碑版本,我們必須做的足夠完善才敢稱之為。 自從17年11月份對外公布以來,KPC已經經過了8個月的迭代,期間發布了幾十個正式版本,但一直沒有到1.0,因為我們覺得1.0是個里程碑版本,我們必須做的足夠完善才敢稱之為1.0。而如今我們有信心對外宣布:KPC 1.0終于來了! 其實距離...
摘要:寫在前面的嘮簡單記錄一下工作中出現的需求和常見的問題,時常記錄總結,希望能在之后的工作中吸取經驗教訓,提高工作效率。只展示一行數據的時候給固定高度為了顯示展開收起按鈕,因為設定分辨率是來回變的,思來想去還是使用了監聽事件。 寫在前面的嘮 簡單記錄一下工作中出現的需求和常見的問題,時常記錄總結,希望能在之后的工作中吸取經驗教訓,提高工作效率。如果可以幫助有同樣問題的同學我會很開心的,有的...
摘要:然后使用,在的上綁定了,很簡單。日歷遍歷的思路這一次的提交主要是確定了日歷組件,怎么寫,具體思路看下面的代碼,盡量通過注釋把思路講的清楚一些。前言 在最近的項目中,大量的嘗試了react hooks,我們的組件庫用的是Next,除了一個地方因為要使用Form + Field的組合,所以使用了class組件,經過了這個項目,也算是總結一些使用的經驗,所以準備自己封裝一個日歷組件來分享一下。以下...
閱讀 547·2023-03-27 18:33
閱讀 732·2023-03-26 17:27
閱讀 630·2023-03-26 17:14
閱讀 591·2023-03-17 21:13
閱讀 521·2023-03-17 08:28
閱讀 1801·2023-02-27 22:32
閱讀 1292·2023-02-27 22:27
閱讀 2178·2023-01-20 08:28