看完你也想編寫自己的 react 外掛

singsong發表於2018-03-10

副標題: 為什麼我要寫這個 react 外掛

圖片懶載入是專案中常用的功能,然而現有 react 懶載入元件庫,用著都不是很爽了 ?。概括一下有如下幾點:

  • 沒有隻針對 image 懶載入元件。多陣列件庫都內建了模組、元件、指令碼、iframe 懶載入功能,而弱化了 image 懶載入功能。
  • 不支援動畫顯示效果。
  • 不靈活,可配置度不高。
  • placeholder 不能元件化。
  • 不支援響應式圖片( picture / srcset )。

react-lazyimg-component

清楚自己想要什麼樣的元件,就自己動手擼唄 ?。於是乎,react-lazyimg-component 就誕生了 ?。我們們先來看看它的效果吧:

singsong: 如果大家有時間,窩還是鼓勵大家自己動手實現一些小外掛。

  • PC 預覽:

使勁猛擊這裡

  • 手機預覽(掃一掃):

qrcode

什麼情況需要使用它

1. 小巧輕便,簡單易用,基本無學習成本

jq

在那個 jQuery 一統天下的年代,擼程式碼就用 jQuery 一把梭。其中 jQuery.lazyload 是一個很常用圖片懶載入外掛。 可能很多像我一樣的小夥伴們,懶載入就直接上 jQuery.lazyload,早已習慣了 jQuery.lazyload 使用。 於是自己就琢磨能否繼承 jQuery.lazyload 使用方法同時保持 react 特有元件特性。這樣可以很快上手~~~~~?

singsong: 這裡只是繼承了 jQuery.lazyload 配置特性,不是完全繼承。畢竟 jQuery 與現在主流的 MVVM 框架思想截然不同。

如果小夥伴們熟悉 jQuery.lazyload , 完全沒有學習成本直接上手 react-lazyimg-component 哈。 只說不是寫,然並卵。那我們來看看它到底好用不:

安裝

// npm
$> npm install react-lazyimg-component
// yarn
$> yarn add react-lazyimg-component
複製程式碼

使用

// 引入
import Lazyimg, { withLazyimg } from 'react-lazyimg-component';

// 呼叫
<Lazyimg
  className="lazy"
  src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
/>;
複製程式碼

是不是很簡單,有木有 ?。上述只是使用 react-lazyimg-component 的預設配置。 這裡我們可以通過配置項來定製懶載入的行為:

// 引入 lazyimg
import Lazyimg, { withLazyimg } from 'react-lazyimg-component';
// 引入 volecity.js
import 'velocity-animate';
import 'velocity-animate/velocity.ui';

// 配置
const config = {
  threshold: 100, // 指定觸發閾值
  js_effect: 'transition.fadeIn', // 支援 velocity.js 動畫效果
};
// 基於配置項生成對應 Lazy 元件
const Lazy = withLazyimg(config);

// 呼叫
<Lazy
  className="lazy"
  src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
/>;
複製程式碼

接下來我們來看看 react-lazyimg-component 都那些配置項:

threshold: 0, // 指定距離底部多少距離時觸發載入
event: 'scroll', // 指定觸發事件,預設為'scroll'
js_effect: undefined, // 顯示圖片的js動畫效果
css_effect: undefined, // 顯示圖片的css動畫效果
container: window, // 指定容器,預設為window
parent: undefined, // 可以指定動畫效果作用於元素的哪個父級元素
appear: null, // 元素出現在可視視窗時觸發appear鉤子函式
load: null,  // 元素圖片的載入完後觸發load鉤子函式
error: null, // 圖片載入出錯時觸發error鉤子函式
node_type: 'img', // 指定生成的節點型別,預設為'img'
placeholder: // 佔位元素,除了支援普通的圖片外,還支援react元件。
  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC',
複製程式碼

是不是很眼熟 ?,如果你熟悉 jquery.lazyload,那麼你只需瞭解如下幾個配置項即可:

  • js_effect: 指定元素顯示的動畫效果,基於velocity.js動畫實現。使用之前需載入velocity.js

  • css_effect: 指定元素顯示的動畫效果,基於animate.css動畫實現。使用之前需安裝animate.css

  • parent: 用於指定動畫效果作用於元素的哪個父級元素。可取值:

    • 父元素的 selector 選擇器(字串)
    • 父級層級 level(整數)
  • node_type: 指定 react 將生成的元素型別,預設為'img'。

  • placeholder: 佔位元素,除了支援普通的圖片外,還支援 react 元件。

2. 支援 velocity.jsanimate.css 動畫效果庫,及自定動畫效果。同時還支援動畫效果作用於父級元素。

  • 指定 js-effect 配置項來配置 velocity.js 動畫效果

注意:js-effect 依賴於 velocity.js。需要確保 velocity.js 已載入。

// 引入 lazyimg
import Lazyimg, { withLazyimg } from 'react-lazyimg-component';
// 引入 volecity.js
import 'velocity-animate';
import 'velocity-animate/velocity.ui';
// 配置
const config = {
  placeholder: 'loading.svg',
  js_effect: 'transition.fadeIn', // 支援 velocity.js 動畫效果
};
const Lazy = withLazyimg(config);
// 呼叫
<Lazy
  className="lazy"
  src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
/>;
複製程式碼

直接上效果了 ?

看完你也想編寫自己的 react 外掛

  • 指定 css-effect 配置項來配置 animate.css 動畫效果

注意:css-effect 依賴於 animate.css。需要確保 animate.css 已安裝。

  // 配置
  const config = {
    js_effect="transition.flipXIn" // 不會生效
    css_effect={['animated', 'rollIn']} // 定製 css 動畫效果
  };
  const Lazy = withLazyimg(config);
  // 呼叫
  <Lazy
    className="lazy"
    src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
  />;
複製程式碼

直接上效果了 ?

看完你也想編寫自己的 react 外掛

  • 指定 parent 配置項指定父級元素動畫效果

singsong: 為什麼懶載入的動畫效果只作用於目標元素,某些條件下作用於目標元素的父級元素會有意想不到效果哦 ?。

<div className="example">
  // 指定動畫效果作用於該父級元素
  <Title title="父級動畫效果" className="sub" />
  <div className="example-img">
    <Lazyimg
      className="lazy"
      src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
      css_effect={['animated', 'flipInY']} // 定製 css 動畫效果
      parent=".example" // 指定父級元素選擇器,也可以指定父級層級level2
    />
  </div>
</div>
複製程式碼

直接上效果了 ?

看完你也想編寫自己的 react 外掛

3. react 元件式 placeholder

singsong: 傳統的 placeholder 通常都是由圖片來代替,為什麼不能用元件來定製,這樣可擴充套件性更高。完全可以擺脫設計師的束縛,咋們開發自由發揮?! 想想有木有有點小雞凍 ?~~~~~~

  • 先定義 placeholder 元件
import React from 'react';
import './style.scss';
export default props => {
  let { className, text, img, children } = props;
  return (
    <div
      className={['placeholder', className]
        .filter(item => {
          if (item) {
            return item;
          }
        })
        .join(' ')}
    >
      {img && <img src={img} className="placeholder-img" />}
      {text && <span className="placeholder-text">{children || text}</span>}
    </div>
  );
};
複製程式碼
  • 指定 placeholder 配置項為上述定義的 placeholder 元件
// 配置
const Lazy = withLazyimg({
  js_effect: 'transition.perspectiveDownIn',
  placeholder: <Placeholder img={require('./loading.svg')} />,
});
// 呼叫
<Lazy
  className="lazy"
  src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
/>;
複製程式碼

直接上效果了 ?

看完你也想編寫自己的 react 外掛

singsong: 圖中小火焰有木有很耀眼~~~~~

接著咋們來看看元件式 placeholder 應用場景案例,直接上效果了 ?

看完你也想編寫自己的 react 外掛

上圖是分類頁通過定製顯示文案的 placeholder 元件來代替普通的灰色圖片,效果是不是看著還行 ?。這是我在實際專案中使用的案例。這裡小夥伴可以自由發揮哈~~~~~。如果你有不錯 idea 可以@我哈,先謝了!

4. 響應式圖片( picture / srcset )

為了實現 web 應用的極致體驗,Progressive Web App 漸進式網頁應用程式越來越受到開發者們重視,其中響應式圖片就是其中一個重要技術項。為了跟著大部隊,咋們也需要了解了解噢!

  • srcset 特性實現響應式圖片
  // dpr
  <Lazyimg
    className="lazy"
    src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
    srcSet="source_1x.png 1x, source_2x.png 2x, source_3x.png 3x, source_3.5x.png 3.5x"
    js_effect="transition.bounceIn"
  />
複製程式碼

直接上效果了 ?

看完你也想編寫自己的 react 外掛

singsong: 這裡 srcset 配合 sizes 特性可以實現更好的效果

  • picture 元素實現響應式圖片
  <picture>
      <source media="(min-width: 650px)" srcSet="https://www.w3schools.com/tags/img_pink_flowers.jpg" />
      <source media="(min-width: 465px)" srcSet="https://www.w3schools.com/tags/img_white_flower.jpg"/>
      <Lazyimg
      className="lazy"
      src={'http://zhansingsong.github.io/lazyimg/22.4582fc71.jpg'}
      js_effect="transition.expandIn"
    />
  </picture>
複製程式碼

直接上效果了 ?

看完你也想編寫自己的 react 外掛

後語

這個外掛是我由專案中提煉出的,個人用著還挺順手,就拿出與大家分享分享。另外,畢竟個人能力有限,如果你發現外掛有問題或有什麼好的建議,也請告知一下,先這裡謝過了 ?。最後歡迎star?、歡迎watch?、歡迎fork?

相關文章