精通react/vue組件設計教你實現一個極具創意的加載(Loading)組件

2020-12-22 酷扯兒

本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫

前言

本文是筆者寫組件設計的第八篇文章, 今天帶大家用5分鐘實現一個極具創意的加載(loading)組件.涉及的核心知識點主要是css3相關特性, 如果大家非常熟悉,可直接跳過介紹直接看正文.

時刻問自己:是否具備創造力?

[筆記]前端組件的一般分類:

通用型組件: 比如Button, Icon等.布局型組件: 比如Grid, Layout布局等.導航型組件: 比如麵包屑Breadcrumb, 下拉菜單Dropdown, 菜單Menu等.數據錄入型組件: 比如form表單, Switch開關, Upload文件上傳等.數據展示型組件: 比如Avator頭像, Table表格, List列表等.反饋型組件: 比如Progress進度條, Drawer抽屜, Modal對話框等.其他業務類型所以我們在設計組件系統的時候可以參考如上分類去設計,該分類也是antd, element, zend等主流UI庫的分類方式.

正文

在開始組件設計之前希望大家對css3和js有一定的基礎,並了解基本的react/vue語法.我們先看看實現後的組件效果:

因為動圖體積太大,就不給大家傳gif了,接下來我們具體分析一下該組件的特點.

1. 組件設計思路

按照之前筆者總結的組件設計原則,我們第一步是要確認需求. 首先我們設計的不是後臺管理系統專用的加載動畫,而是作為一個C端產品的功用型加載動畫.我們都知道加載動畫的作用是:在用戶等待網頁時能看到有用的信息,比如網站介紹,引導, 公司信息等,緩解用戶焦慮. 作為一名產品經理或者用戶體驗師, 這種個性化的加載體驗效果往往是更好的.

而加載動畫一般會分為策略型加載動畫通用加載動畫,通用加載動畫我就不說了,大家平時做的系統大部分應該都是通用型加載動畫. 我這裡介紹一下策略型加載動畫.

策略型加載動畫往往用在C端產品或者系統中,用來為用戶提供更多的引導信息, 當用戶首次訪問系統或者網站時, 由於某種主動型引導(網站在加載時或者切換頁面時故意給用戶看到的加載信息)或者環境原因(網絡,帶寬限制導致的加載過慢,此時出現加載動畫), 這些加載信息往往帶有某種用途,比如對於個人博客網站, 這個加載動畫可以是博主的介紹,博主的宣傳信息,github地址等, 對於企業來說,可能是某個新功能的介紹, 網站服務信息的介紹,聯繫方式等.

在了解完以上背景後, 我們來看看組件設計的線框圖:

對於react選手來說,如果沒用typescript,建議大家都用PropTypes, 它是react內置的類型檢測工具,我們可以直接在項目中導入. vue有自帶的屬性檢測方式,這裡就不一一介紹了.

通過以上需求分析, 其實一個加載動畫非常簡單, 不會涉及到太多功能, 主要在於css3動畫的使用. 具體屬性有:

加載動畫出現時的加載文本控制加載狀態的state接下來我們就來看看具體實現.

2. 基於react實現一個Loading組件

因為該組件不會涉及到太多的js代碼,主要是html和css,所以我們直接先構建組件的結構:

/**

* 骨架屏組件(SEO)

* @param {isLoading} bool 加載狀態

* @param {loadingText} string 加載時的加載文本

*/

export default function Skeleton(props) {

let { isLoading = true, loadingText = '正在為您瘋狂加載...' } = props

return isLoading ? <div className={styles.skeletonWrap}>

<div className={styles.skeletonContent} data-loadingText={loadingText}>

自定義的引導內容

</div>

</div> : null

}

自定義的引導內容這裡我就不介紹了, 主要根據不同的網站性質靈活配置.我主要介紹加載動畫部分, 其實原理也很簡單, 我們在skeletonContent元素上使用一個::after偽對象來實現窗簾動畫即可.

在實現動畫前大家最好對關鍵幀動畫有所了解,我相信大家都比較了解. 這種關窗簾動畫一種實現方式就是通過控制元素寬度, 從0到100%, 然後添加適當的要是優化即可. 動畫的代碼如下:

@keyframes spread {

0% {

width: 0;

}

100% {

width: 100%;

}

}

我們只需要在::after裡直接這樣使用就好了:

&::after {

animation: spread 18s 3s infinite;

}

這樣動畫已經做完了, 但是為了讓動畫更完整,我們還要考慮一個事實, 如果窗簾寬度從0慢慢變化的過程中, 加載動畫的文字一直保持一個顏色會很生硬, 如下圖:

所以說作為一個好的互動設計來說, 要讓交互體驗更順暢,這裡提供一種方式,就是加載的文本在窗簾寬度變化的同時,文字的透明度從0變化到1,這樣就會柔和很多, 所以動畫可以這麼改:

&::after {

color: rgba(255, 255, 255, 0);

animation: spread 18s infinite;

}

@keyframes spread {

0% {

width: 0;

color: rgba(255, 255, 255, 0);

}

100% {

width: 100%;

color: rgba(255, 255, 255, 1);

}

}

效果如下:

最後我們來實現loadingText. 這塊也涉及到一個知識點, 因為加載文本其實主要是用來修飾元素的,並沒有太多的語義化場景, 所以我們會放在::after偽對象的content裡, 但是一般content是在css裡寫的,那麼如何實現動態文本呢? 我們這裡就要採用css的屬性內容這個api. content不僅僅可以接收一個字符串,還可以接收attr這個關鍵字,關鍵字裡面的內容是元素的自定義屬性, 比如:

<div data-tip="loading"></div>

那麼我們在css裡可以通過這種方式直接使用data-tip屬性的值:

div::after{

content: attr(data-tip)

}

通過以上的方式我們可以在::after裡直接拿到data-tip的內容了, content其實還有更多的功能,比如用純css實現一個計數器,大家可以研究學習一下.

這樣,我們的Loading組件就完成了, 還有一個問題是我代碼裡的組件命名,為什麼叫骨架屏呢?其實我們只要改變內容結構, 它立馬就可以變成一個骨架屏,所以命名這塊可以按照實際需求來確定.

3. 健壯性支持

我們採用react提供的propTypes工具

import PropTypes from 'prop-types'

// ...

Skeleton.propTypes = {

isLoading: PropTypes.bool,

loadingText: PropTypes.string

}

組件完整css代碼如下:

.skeletonWrap {

position: absolute;

left: 0;

right: 0;

top: 0;

bottom: 0;

background-color: rgba(0,0,0, .6);

.skeletonContent {

position: relative;

margin: 200px auto 0;

padding: 20px;

width: 800px;

display: flex;

align-items: center;

border-radius: 8px;

overflow: hidden;

background-color: #fff;

&::after {

content: '正在為您瘋狂加載...';

position: absolute;

top: 0;

left: 0;

display: flex;

align-items: center;

justify-content: center;

width: 0;

height: 100%;

border-right: 2px solid #ccc;

box-shadow: 0 0 8px #000;

background: #096;

color: rgba(255, 255, 255, 0);

font-size: 24px;

white-space: nowrap;

animation: spread 18s 3s infinite;

}

@keyframes spread {

0% {

width: 0;

color: rgba(255, 255, 255, 0);

}

100% {

width: 100%;

color: rgba(255, 255, 255, 1);

}

}

.imgBox {

margin-right: 20px;

width: 400px;

.img {

width: 100%;

height: 200px;

background-color: #ccc;

}

img {

width: 100%;

}

}

.rightBox {

flex: 1;

.tit {

margin-top: 8px;

margin-bottom: 8px;

font-size: 22px;

}

.labelWrap {

span {

margin: 3px;

display: inline-block;

font-size: 12px;

padding: 2px 6px;

border-radius: 3px;

color: #fff;

background-color: #58bd6b;

}

}

.desc {

color: rgb(44, 44, 44);

font-size: 14px;

}

}

}

}

關於代碼中的css module和classnames的使用大家可以自己去官網學習,非常簡單.如果不懂的可以提問,筆者看到後會第一時間解答.

4. 使用Skeleton組件

我們可以通過如下方式使用它:

<Skeleton loadingText="玩命加載中..." />

筆者已經將實現過的組件發布到npm上了,大家如果感興趣可以直接用npm安裝後使用,方式如下:

npm i @alex_xu/xui

// 導入xui

import {

Button,

Skeleton,

Empty,

Progress,

Tag,

Switch,

Drawer,

Badge,

Alert

} from '@alex_xu/xui'

該組件庫支持按需導入,我們只需要在項目裡配置babel-plugin-import即可,具體配置如下:

// .babelrc

"plugins": [

["import", { "libraryName": "@alex_xu/xui", "style": true }]

]

npm庫截圖如下:

最後

後續筆者將會繼續實現

modal(模態窗),badge(徽標),table(表格),tooltip(工具提示條),Skeleton(骨架屏),Message(全局提示),form(form表單),switch(開關),日期/日曆,二維碼識別器組件等組件, 來復盤筆者多年的組件化之旅.

相關焦點

  • 精通react/vue組件設計之配合React Portals實現一個(Drawer)組件
    通過組件的設計過程,大家會接觸到一個完成健壯的組件設計思路和方法,也能在實現組件的過程逐漸對react/vue的高級知識和技巧有更深的理解和掌握,並且在企業實際工作做遊刃有餘.作為數據驅動的領導者react/vue等MVVM框架的出現,幫我們減少了工作中大量的冗餘代碼, 一切皆組件的思想深得人心.
  • 《精通react/vue組件設計》之快速實現一個可定製的進度條組件
    今天要來實現一個高可定製的進度條組件,在介紹組件設計之前,我們先牢記以下幾個原則.每一個組件只負責某一特定的表現或者功能)正文在開始組件設計之前希望大家對css3和js有一定的基礎.我們先看看實現後的組件效果:上圖可以知道封裝後的進度條組件通過對外暴露的接口(react/vue裡面可以看做
  • 精通react/vue組件設計之實現一個輕量級可擴展的模態框組件
    正文在開始組件設計之前希望大家對css3和js有一定的基礎,並了解基本的react/vue語法.我們先來解構一下Modal組件, 一個Modal分為以下幾個部分:編輯搜圖每一個區塊都可以自定義配置, 也可以組合其他組件.實現後的組件效果:編輯搜圖1.
  • 《精通react/vue組件設計》之實現一個健壯的警告提示(Alert)組件
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言本文是筆者寫組件設計的第七篇文章, 今天帶大家實現一個自帶主題且可關閉的Alert組件, 該組件在諸如Antd或者elementUI等第三方組件庫中都會出現,主要用來提供系統的用戶反饋
  • 精通react/vue組件設計之實現一個Tag(標籤)和Empty(空狀態)組件
    "辛勤勞動",而是要根據已有前端的開發經驗,總結出一套自己的高效開發的方法.作為數據驅動的領導者react/vue等MVVM框架的出現,幫我們減少了工作中大量的冗餘代碼, 一切皆組件的思想深得人心.所以, 為了讓工程師們有更多的時間去考慮業務和產品迭代,我們不得不掌握高質量組件設計的思路和方法.所以筆者將花時間去總結各種業務場景下的組件的設計思路和方法,並用原生框架的語法去實現各種常用組件的開發,希望等讓前端新手或者有一定工作經驗的朋友能有所收穫
  • 精通React/Vue系列之帶你實現一個功能強大的通知提醒框
    本文將會使用React來開發該組件,也會使用到Javascript中常用的一些設計模式,比如單例模式,但是不管你使用什麼框架來實現,原理都是通用的,如果感興趣的朋友可以用vue也實現以一下。正文在開始組件設計之前希望大家對css3和js有一定的基礎,並了解基本的react/vue語法.我們先來解構一下Notification組件, 一個Notification分為以下幾個部分:每一個區塊都可以自定義配置, 也可以組合其他組件.並且我們可以配置提醒框出現的位置,就像antd
  • 基於jsoneditor二次封裝一個可實時預覽的json編輯器組件react版
    ,這樣一方面可以提高組件復用性和可擴展性,另一方面也帶來了項目開發的靈活性和可維護,方便多人開發協作.接下來文章將介紹如何使用react,開發一個自定義json編輯器組件.我們這裡使用了jsoneditor這個第三方庫,官方地址: jsoneditor 通過實現一個json在線編輯器,來學習如何一步步封裝自己的組件(不限於react,vue,原理類似).
  • 如何用純css打造類materialUI的按鈕點擊動畫並封裝成react組件
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言作為一個前端框架的重度使用者,在技術選型上也會非常注意其生態和完整性.筆者先後開發過基於vue,react,angular等框架的項目,碧如vue生態的elementUI, ant-design-vue, iView等成熟的UI框架
  • vue使用vant實現tab切換,使用nutui實現上拉加載下拉刷新
    本次demo主要實現的功能:1. 使用第三方 vant 組件庫的tab標籤實現tab欄的切換,2.使用第三方 nutui 組件庫實現各tab中的內容列表的上拉加載,下拉刷新。準備工作:a.在當前的vue項目中安裝 vant ui庫:npm i vant -S (或npm install vant -S)b.在當前的vue項目中安裝 @nutui/nutui 庫 :
  • React源碼之組件的實現與首次渲染
    react: v15.0.0 本文講 組件如何編譯 以及 ReactDOM.render 的渲染過程。 babel 的編譯 babel 將 React JSX 編譯成 JavaScript.
  • 手把手教你用JS/Vue/React實現幸運水果機(80後情懷之作)
    項目體驗地址免費視頻教程分別使用原生JS,Vue和React,手把手教你開發一個H5小遊戲,快速上手Vue和React框架的使用。項目截圖在線體驗在線體驗遊戲介紹幸運水果機是一款街機遊戲,遊戲界面由24個方格拼接成一個正方形,每個方格中都有一個不同的水果圖形,方格下都有一個小燈。
  • 供我們選擇的 Vue 組件庫還有很多!
    Element 插件,你可以用它們快速地搭建一個基於 Element 的項目。特別是微信 H5 開發的朋友,這款組件庫的 UI 是基於微信官方樣式設計的,十分貼合,建議使用。相關開源項目:vux2.5-webapp:一個基於 vux 開發的商城項目。
  • 快速在你的vue/react應用中實現ssr(服務端渲染)
    默認情況下,可以在瀏覽器中輸出自定義組件,進行生成 DOM和操作 DOM, 也就是我們常說的客戶端渲染, 並且我們大部分主流的場景都是SPA(單頁面)應用, 而隨著 SPA尤其是 React、Vue、Angular 為代表的前端框架的流行
  • 10個實用技巧讓你的 Vue 代碼更優雅
    例如,如果你的 Vue 實例有一個 data 屬性 attributeName,其值為 href,那麼這個綁定將等價於 v-bind:href同樣地,你可以使用動態參數為一個動態的事件名綁定處理函數:<button v-on:[eventName]="handler"></button>//簡寫<button
  • 10個簡單的技巧讓你的 vue.js 代碼更優雅
    例如,如果你的 Vue 實例有一個 data 屬性 attributeName,其值為 href,那麼這個綁定將等價於 v-bind:href同樣地,你可以使用動態參數為一個動態的事件名綁定處理函數:<button v-on:[eventName]="handler">
  • Vue.js 教程:構建一個特斯拉汽車餘電計算器
    作為本教程的起點,請克隆這個 Github 存儲庫:https://github.com/petereijgermans11/workshop-reactjs-vuejs然後轉至 vuejs-app 目錄。
  • 基於Vue實現一個有點意思的拼拼樂小遊戲
    vue的第三方移動端ui庫,筆者推薦如下:Mint 餓了麼推出的移動端ui庫NutUI 一套京東風格的移動端組件庫muse-ui 基於MaterialUI風格的移動端UI組件cube-uicd pinpinle && yarn start複製代碼關於vue-cli3配置實戰,可以移步 一張圖教你快速玩轉vue-cli3H5遊戲核心功能介紹目前筆者主要整理樂如下核心功能,接下來筆者會一一帶大家實現
  • Vue.js布局
    靜態布局包裝器組件:使用普通組件(包含布局不同部分的一個或多個插槽)作為視圖的包裝器,它提供了很大的靈活性,並且感覺不像條件渲染方法那麼髒。/layouts/LayoutDefault.vue';export default { name: 'Home', components: { LayoutDefault, },};</script>說明:Home.vue組件實現LayoutDefault
  • vue 具名插槽詳解專題及常見問題 - CSDN
    插槽含義:就是引入子組件後,在插入子組件元素中添加信息或者標籤,使得子組件的指定位置插入信息或者標籤插槽有三種:默認插槽、具名插槽、作用域插槽,由於vue2.6.0後對插槽進行修改,但是兼容2.6.0前的版本,博文中只說明2.6.0後的插槽,vue3.0後面會去除2.60前的版本兼容  一、默認插槽<
  • React、Angular和Vue三種最流行的前端框架哪一個最好?
    因此,在深入比較之前,我們首先需要確定哪一個是必需的 - 一個庫或一個框架?實際上,庫被設計來執行一些特定的任務,而且通常並不複雜。因此,如果我們使用庫來構建我們的應用程式,那麼我們需要為每個任務選擇一個庫,以及設置任務運行者。庫的主要優點是我們可以完全控制應用程式。但問題是建立該項目需要更多的時間。另一方面,框架被設計用於執行更複雜的事情。