React實現一個通用骨架屏元件示例
目錄
- 骨架屏是什麼?
- Demo
- 設計思路
- 具體實現
骨架屏是什麼?
找到這裡的同志,或多或少都對骨架屏有所瞭解,請容許我先囉嗦一句。骨架屏(Skeleton Screen)是一種優化使用者弱網體驗的方案,可以有效緩解使用者等待的焦躁情緒。
Demo
先看個demo 大概瞭解下最終的產物及其使用方式
npm install obiusm-react-components
import { Skeleton } from 'obiusm-react-components';
<Skeleton isVisible={true}> <div className="wrapper"> <div className="content1"></div> <div data-skeleton-ignore={true}>123456</div> <div className="content2"></div> <div className="content3" data-skeleton-style={{ width: '50%' }}></div> </div> </Skeleton>
只需要在自己寫的元件外面包一層決定其是否顯示就可以了
設計思路
骨架可以在真實內容沒有加載出來前讓使用者提前感知,可以提高使用者體驗 如果我們每次寫元件的時候都要為其定製骨架,那就顯得相當繁瑣
得益於React props的這種資料資料傳遞方式,我們在props中可以輕鬆拿到整顆ReactElement的樹。 那麼我們只需要去遞迴遍歷這個樹從而去模仿其結構,複製其class就可以實現自動生成骨架了。
但在具體的使用上,我們可能只需要結構前幾層的結構而不需要模擬整顆樹的結構,也有可能自動生成的樣式太醜我們需要定製其節點樣式,還有可能我們不需要關注一些浮層類的內容或者說想忽略某一個節點
所以大概需要實現以下幾個功能
- 設定遞迴深度
- 提供忽略節點的方法
- 提供定製骨架節點樣式的方法
具體實現
首先定義一個元件函式來決定是渲染骨架屏還是真實元素
function Skeleton(props: Props) { if (!props) { return <div />http://www.cppcns.com; } if (props.isVisible) { return createModal(props.children,props.depth || 4,0); } else { return props.children ? props.children : <div />; jIHxNmYYI} }
createModal 對Skeleton下面包住的div進行遞迴遍歷, 每次遞迴的時候將current+1並傳遞下去,這樣我們可以判斷已經遞迴了幾層了 判斷一下每個節點上data-skeleton-ignore是否有data-skeleton-style從而特殊處理就可以了
const createModal = (child: ReactElement,depth: number,current: number) => {
if (
depth === current ||
(child && child.props && child.props['datahttp://www.cppcns.com-skeleton-ignore'])
) {
return;
}
if (
child &&
child.props &&
child.props.children &&
Array.isArray(child.props.children) &&
current < depth - 1
) {
return (
<div
className={`${
child.props.className !== undefined ? child.props.className : ''
} ${'react-skeleton'}`}
style={
child.props && child.props['data-skeleton-style']
? child.props['data-skeleton-style']
: {}
}
key={Math.random() * 1000}
>
{child.props.children && child.props.children.length > 0
? child.props.children.map((child: any) => {
return createModal(child,depth,current + 1);
})
: '*'}
</div>
);
} else {
return (
<div
className={`${
child.props && child.props.className ? child.props.className : ''
} ${'react-skeleton2'}`}
style={
child.props && child.props['data-skeleton-style']
? child.props['data-skeleton-style']
: {}
}
key={Math.random() * 1000}
>
*
</div>
);
}
};
完整程式碼及其使用文件
完整程式碼 obiusm-react-components
文件 https://magic-zhu..io/obiusm-react-components-docs/components/skeleton/
到此這篇關於React實現一個通用骨架屏元件示例的文章就介紹到這了,更多相關React 骨架屏內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!