要做移动端应用,同时要适配ios、android和微信。搜索、试验、思考…几天内进行了好几轮,最终决定采用react-native & antd-mobile来实现我们的目的。
思路&选择
在网上搜索,看到了多种方案。第一种,利用redux,共享业务逻辑,自己维护两套UI组件;第二种,利用react-native-web,先写移动端,再将移动端转换成H5;第三种:利用styled-components来封装UI组件,也要维护两套UI;第四种:利用antd-mobile来适配三端。
最终决定选择antd-mobile方式,因为其本身就是一套很好的解决方案,文档较全,实现方式简单,虽然是两套代码,但现有组件已经很多,也容易扩展。我已经修复了一个小bug,自行发布到了npm,并替换到项目中,这样能够快速方便的实现自己想要的组件。
代码编写原则
所有的界面元素都使用antd-mobile的组件来实现,不够用的,不符合要求的,直接改动antd-mobile。
关键步骤
webpack2配置
antd-mobile要支持H5,在要webpack中进行配置,打包web版的代码。
import antd-mobile
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [{
loader:'babel-loader',
options:{
presets: ['es2015', "stage-2", 'react'],
plugins: [ ["transform-runtime"],["import", {libraryName: "antdm", style: true}]
],
}
}],
},
resolve web.*
resolve: {
mainFiles: ["index.web","index"],// 这里哦
modules: ['app', 'node_modules', path.join(__dirname, '../node_modules')],
extensions: [
'.web.tsx', '.web.ts', '.web.jsx', '.web.js', '.ts', '.tsx',
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
布局组件
antd-mobile文档中只提了复杂的组件,但我们在H5中经常用的div与native中的View应该如何处理呢?看文档、搜索,都没有找到我想要的方法;在github中看别人家的代码,发现都是直接用了div或native的View,不能同时适配三端。以至于我一度想引入styled-components来封装,但总觉得引入styled-components只用来处理几个基本元素,不划算。最后是想起来要看看antd-mobile的源码,在antd-mobile中来做引入styled-components做的事,不就可以了吗!结果发现antd-mobile已经有封装了,就是View。
问题基本解决了,但运行时会有如下的警告信息:
Warning: Unknown prop `Component` on <div> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
in div (created by View)
in View (at Root.js:15)
in Provider (at Root.js:14)
in Root (at index.js:20)
in AppContainer (at index.js:19)
看源代码,是有个小bug,顺手修改了,编译,运行,问题解决。提交pull requests,人家不可能很快的更新,而且可能有的改动只是为了适应我们自己的项目,因此发布到npm中,名字叫antdm。
程序入口
入口文件会有三个,原则是尽量保持简单
ios:index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import Root from './src/containers/Root';
import configureStore from './src/store/configureStore.js';
const store = configureStore();
class T3 extends Component {
render() {
return (
<Root store={store}/>
);
}
}
AppRegistry.registerComponent('t3', () => T3);
web:/src/web/index.js
import React from 'react';
import { render } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import Root from '../containers/Root';
import configureStore from '../store/configureStore';
const store = configureStore();
render(
<AppContainer>
<Root store={store} />
</AppContainer>,
document.getElementById('root')
)
android:index.android.js
还未编写,应该与ios差不多。
项目地址
https://git.oschina.net/zhoutk/t3.git
https://github.com/zhoutk/t3.git
使用方法
git clone https://git.oschina.net/zhoutk/t3.git
or git clone https://github.com/zhoutk/t3.git
cd t3
npm i
ios: npm run ios
web: npm run web
小结
利用react-native和antd-mobie基本达到移动端适配三端的要求,但在做项目的同时,可能需要基于antd-mobile逐步建立起一套适合自己的UI组件。谢谢阿里的兄弟们!