React Native Icon方案:react-native-svg

原文地址:github.com/HuJiaoHJ/bl…css

網上 React Native 的 icon 實現大都是使用iconfont方案,即:react-native-vector-iconshtml

此方案存在一個問題:強依賴客戶端打包,即每新增圖標,就須要客戶端從新打包,資源管理上不能作到 RN 與客戶端解耦react

爲了不這個問題,使用了SVG方案:react-native-svg 來實現Icongit

接下來將從三個方面進行分享:github

  • react-native-svg 使用
  • Icon組件實現及2Web
  • Icon組件使用

此文會涉及部分 React Native 轉 web 的知識,使用的是 react-native-web 方案,能夠看看我以前寫的文章:react native轉web方案:react-native-webweb

react-native-svg 使用

安裝

npm install react-native-svg --save
複製代碼

Link native code

react-native link react-native-svg
複製代碼

以上操做,其實就是將 react-native-svg 的依賴安裝到客戶端中,進行了上面的操做,基本已自動完成安裝依賴,可是在部分IOS上會存在問題,如遇到問題能夠去 react-native-svg 查看解決方案npm

react-native-svg-uri

react-native-svg-uri 支持在RN中經過一個URL或者靜態文件渲染svg,同時也支持傳入svg字符串,將其渲染json

使用以下:react-native

// 安裝
npm install react-native-svg-uri --save
// 確保已在客戶端中安裝了 react-native-svg 依賴,若未安裝依賴,執行:
react-native link react-native-svg
複製代碼

下面將使用 react-native-svg-uri 來實現Icon組件,這個庫源碼只有兩個js文件,有興趣的小夥伴能夠自行了解~bash

Icon組件實現及2web

實現

上面咱們有提到,react-native-svg-uri 支持傳入svg字符串來渲染svg,因此能夠將多個svg文件經過腳本的形式轉換成一個js對象或者一個json文件,其格式以下:

svg.js

export default {
    "arrow-left": "<svg t=\"1533091848499\" class=\"icon\" style=\"\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"579\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"32\" height=\"32\"><defs><style type=\"text/css\"></style></defs><path d=\"M769.405 977.483a68.544 68.544 0 0 1-98.121 0L254.693 553.679c-27.173-27.568-27.173-72.231 0-99.899L671.185 29.976c13.537-13.734 31.324-20.652 49.109-20.652s35.572 6.917 49.109 20.652c27.173 27.568 27.173 72.331 0 99.899L401.921 503.681l367.482 373.904c27.074 27.568 27.074 72.231 0 99.899z\" fill=\"\" p-id=\"580\"></path></svg>"
}
複製代碼

在使用時,能夠經過獲取對應 key 的 value 傳給 react-native-svg-uri 渲染

上面的轉換腳本能夠參考:svg2json,代碼:github.com/HuJiaoHJ/sv…

作好文件轉換以後,咱們能夠開發Icon組件啦

index.js

import createIconSet from './create-icon-set';
// 即上面轉換獲得的 svg.js
import svg from './svg';

const Icon = createIconSet(svg, 'rn_components');

export default Icon;

export { createIconSet };
複製代碼

creact-icon-set.native.js

import React, { Component } from 'react';
import SvgUri from 'react-native-svg-uri';

export default function createIconSet(svg, fontName) {
    return class Icon extends Component {
        render () {
            const { icon, color, size, style } = this.props;
            let svgXmlData = svg[icon];

            if (!svgXmlData) {
                let err_msg = `no "${icon}"`;
                throw new Error(err_msg);
            }
            return (
                <SvgUri width={size} height={size} svgXmlData={svgXmlData} fill={color} style={style} /> ); } }; } 複製代碼

以上就是Icon組件的實現

2web

對RN2web感興趣的小夥伴能夠看看:react native轉web方案:react-native-web

在此基礎上,咱們須要對咱們Icon組件支持2web,因爲沒有對應的web組件,因此須要咱們自行實現對應web的組件

web端咱們使用iconfont來作Icon組件(注意:iconfont不支持多色icon,多色的icon只能選擇svg或者img)

仍是svg文件轉換的問題,咱們須要先將svg文件轉換成iconfont,即

這樣咱們就能向常規web同樣使用iconfont啦

上面的轉換工具能夠參考:svg2iconfont,代碼:github.com/HuJiaoHJ/sv…

固然,要注意記得將生成的iconfont.css文件引入頁面html中,接下來看看2web的Icon組件實現,不須要額外新建文件夾,只需在相同文件夾下新增 creact-icon-set.js 文件(注意到上面RN的文件是 creact-icon-set.native.js),這在實際使用過程當中,會自動識別這兩個文件

creact-icon-set.js

import React, { Component } from 'react'
import { createElement, StyleSheet } from 'react-native'

export default function createIconSet(svgs, fontName) {
  return class Icon extends Component {
    render() {
      const { icon, color, size, style } = this.props
      const styles = StyleSheet.create({
        iconStyle: {
          color,
          fontSize: size,
        },
      })
      const props = {
        className: `${fontName ? fontName + '-' : 'icon-'}${icon}`,
        style: StyleSheet.compose(
          style,
          styles.iconStyle
        ),
      }
      return createElement('i', props)
    }
  }
}
複製代碼

若是看了 react native轉web方案:react-native-web ,應該就能知道 import { createElement, StyleSheet } from 'react-native' 其實是 import { createElement, StyleSheet } from 'react-native-web',沒錯,就是直接使用的 react-native-web 的 API 來開發轉web以後的組件

以上就完成了Icon組件的2web支持

Icon組件使用

咱們怎麼使用呢?有兩種狀況:

使用Icon組件自帶icon

Icon組件會自帶一些經常使用的icon,在使用這些icon時,使用較爲簡單,直接引入,以下使用:

// 引入
import Icon from 'Icon';

// 使用
<Icon icon={'arrow-left'} size={30}/>
複製代碼

注意:若是須要支持2web,須要將對應的 iconfont.css 引入到頁面html中

使用業務icon

若是須要添加業務icon,有以下兩步:

一、將svg轉換成js文件(如須要支持2web,還需生成iconfont)

這部分就不詳細講了,能夠參考上面的內容

二、調用 createIconSet 新建 CIcon組件

代碼以下:

import React from 'react'
// 引入Icon組件的 createIconSet 方法
import { createIconSet } from 'Icon'
// 包含業務svg的js文件
import svgs from './svgs'

// 傳入業務svg的js對象,生成CIcon組件
const CIcon = createIconSet(svgs)

export default function () {
  return Object.keys(svgs).map((item, index) => (
    // 使用
    <CIcon icon={item} color={'#000'} size={50} key={index} />
  ))
}
複製代碼

以上全部代碼可在我的開發的RN組件庫的項目中查看到:rn_components,組件庫如今纔剛開始建設,後續會不斷完善

寫在最後

以上就是我對 React Native Icon方案:react-native-svg 的分享,但願能對有須要的小夥伴有幫助~~~

喜歡個人文章小夥伴能夠去 個人我的博客 點star ⭐️

相關文章
相關標籤/搜索