内容简介:原文地址:网上 React Native 的 icon 实现大都是使用iconfont方案,即:此方案存在一个问题:强依赖客户端打包,即每新增图标,就需要客户端重新打包,资源管理上不能做到 RN 与客户端解耦
原文地址: github.com/HuJiaoHJ/bl…
网上 React Native 的 icon 实现大都是使用iconfont方案,即: react-native-vector-icons
此方案存在一个问题:强依赖客户端打包,即每新增图标,就需要客户端重新打包,资源管理上不能做到 RN 与客户端解耦
为了避免这个问题,使用了SVG方案: react-native-svg 来实现Icon
接下来将从三个方面进行分享:
- react-native-svg 使用
- Icon组件实现及2Web
- Icon组件使用
此文会涉及部分 React Native 转 web 的知识,使用的是 react-native-web 方案,可以看看我之前写的文章: react native转web方案:react-native-web
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 查看解决方案
react-native-svg-uri
react-native-svg-uri 支持在RN中通过一个URL或者静态文件渲染svg,同时也支持传入svg字符串,将其渲染
使用如下:
// 安装 npm install react-native-svg-uri --save // 确保已在客户端中安装了 react-native-svg 依赖,若未安装依赖,执行: react-native link react-native-svg 复制代码
下面将使用 react-native-svg-uri 来实现Icon组件,这个库源码只有两个js文件,有兴趣的小伙伴可以自行了解~
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,有如下两步:
1、将svg转换成js文件(如需要支持2web,还需生成iconfont)
这部分就不详细讲了,可以参考上面的内容
2、调用 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 ,组件库现在才刚开始建设,后续会不断完善
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 10 种跨域解决方案(附终极方案)
- React 服务端渲染方案完美的解决方案
- Hadoop小文件解决方案-基于文件整合的解决方案
- 关于当前公开的组件化方案存在的问题与解决方案探索
- iOS 关于全面屏适配的方案及UI在不同尺寸下适配方案
- iOS 关于全面屏适配的方案及UI在不同尺寸下适配方案
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数字化生存
(美)Nicholas Negroponte(尼古拉·尼葛洛庞帝) / 胡泳、范海燕 / 电子工业出版社 / 2017-1-1 / 68.00
《数字化生存》描绘了数字科技为我们的生活、工作、教育和娱乐带来的各种冲击和其中值得深思的问题,是跨入数字化新世界的*指南。英文版曾高居《纽约时报》畅销书排行榜。 “信息的DNA”正在迅速取代原子而成为人类生活中的基本交换物。尼葛洛庞帝向我们展示出这一变化的巨大影响。电视机与计算机屏幕的差别变得只是大小不同而已。从前所说的“大众”传媒正演变成个人化的双向交流。信息不再被“推给”消费者,相反,人们或他......一起来看看 《数字化生存》 这本书的介绍吧!