时间: 2020-08-23|tag:36次围观|0 条评论

taro初探:使用taro构建微信小程序基础教程插图
u=1650344933,1086893001&fm=173&app=25&f=JPEG.jpg

背景

众所周知如今市面上端的形态多种多样,手机Web、ReactNative、微信小程序, 支付宝小程序, 快应用等,每一端都是巨大的流量入口,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。目前比较流行的框架有wepy, mpvue ,taro
WEPY tencent.github.io/wepy/document腾讯团队开源的一款类vue语法规范的小程序框架,借鉴了Vue的语法风格和功能特性,支持了Vue的诸多特征,比如父子组件、组件之间的通信、computed计算属性、wathcer监听器、props传值、slot槽分发,Mixin混入等。WePY发布的第一个版本是2016年12月份,也就是小程序刚刚推出的时候,到目前为止,WePY已经发布了52个版本, 最新版本为1.7.2;MpVue mpvue.com/mpvue/#-html美团团队开源的一款使用 Vue.js 开发微信小程序的前端框架。使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力。mpvue在发布后的几天间获得2.7k的star,上升速度飞起,截至目前为止已经有13.7k的star;Taro taro.aotu.io/京东凹凸实验室开源的一款使用 React.js 开发微信小程序的前端框架。它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验,同时因为使用了react的原因所以除了能编译h5, 小程序外还可以编译为ReactNative;对比如下:

taro初探:使用taro构建微信小程序基础教程插图1
16287204-e1b97e9b228f8464.jpg

本文主要讲一下京东凹凸实验室的Taro.个人感觉是这三种框架中最好用的。

Taro 是什么?

Taro 是由京东 - 凹凸实验室打造的一套遵循 React 语法规范的多端统一开发框架。
Taro 是一套遵循 React语法规范的 多端开发 解决方案。

使用 Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信/百度/支付宝/字节跳动小程序、QQ轻应用、 H5、React-Native React语法规范,它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验。

import Taro, { Component } from '@tarojs/taro'import { View, Button } from '@tarojs/components'export default class Index extends Component {  constructor () {    super(...arguments)    this.state = {      title: '首页',      list: [1, 2, 3]    }  }  componentWillMount () {}  componentDidMount () {}  componentWillUpdate (nextProps, nextState) {}  componentDidUpdate (prevProps, prevState) {}  shouldComponentUpdate (nextProps, nextState) {    return true  }  add = (e) => {    // dosth  }  render () {    return (      <View className='index'>        <View className='title'>{this.state.title}</View>        <View className='content'>          {this.state.list.map(item => {            return (              <View className='item'>{item}</View>            )          })}          <Button className='add' onClick={this.add}>添加</Button>        </View>      </View>    )  }}

相关连接

Github:

https://github.com/NervJS/taro

官网

https://taro.aotu.io/

为什么要使用Taro?

1.一次编写,多端运行

既然是一个多端解决方案,Taro 最重要的能力当然是写一套代码输出多端皆可运行的代码。目前 Taro 已经支持一套代码同时生成 H5 和微信小程序,App(React Native)端也即将支持,同时诸如快应用等端也将于近期得到支持。

taro初探:使用taro构建微信小程序基础教程插图2
platforms (2).jpg

同时 Taro 也已经投入到了生产环境使用,目前已经支撑了一个 3 万行代码小程序 TOPLIFE 的开发,以及部分京东购物小程序和一起有局小程序,未来也将会支撑更多的京东核心业务小程序。

taro初探:使用taro构建微信小程序基础教程插图3
u=558497892,3943524215&fm=173&app=25&f=JPEG.jpg
2.现代前端开发流程

和微信自带的小程序框架不一样,Taro 积极拥抱社区现有的现代开发流程,Taro 立足于微信小程序开发,众所周知小程序的开发体验并不是非常友好,比如小程序中无法使用 npm 来进行第三方库的管理,无法使用一些比较新的 ES 规范等等,针对小程序端的开发弊端,Taro 具有以下的优秀特性

taro初探:使用taro构建微信小程序基础教程插图4
image.png
import Taro from '@tarojs/taro'Taro.setStorage({ key: 'key', data: 'value' })  .then(res => console.log(res))
3.和 React 完全一致的 API 和组件化系统

在 Taro 中,你不用像小程序一样区分什么是 App 组件,什么是 Page 组件,什么是 Component 组件,Taro 全都是 Component 组件,并且和 React 的生命周期完全一致。可以说,一旦你掌握了 React,那就几乎掌握了 Taro。而学习 React 的资源也几乎是汗牛充栋,完全不用担心学不会。

Taro 和 React 一样,同样使用声明式的 JSX 语法。相比起字符串的模板语法,JSX 在处理精细复杂需求的时候会更得心应手。

class LoginStatus extends Component {  render () {    const isLoggedIn = this.props.isLoggedIn    // 这里最好初始化声明为 `null`,初始化又不赋值的话    // 小程序可能会报警为变量为 undefined    let status = null    if (isLoggedIn) {      status = <Text>已登录</Text>    } else {      status = <Text>未登录</Text>    }    return (      <View>        {status}      </View>    )  }}// app.jsimport LoginStatus from './LoginStatus'// 这样会渲染 `已登录`class App extends Component {  render () {    return (      <View>        <LoginStatus isLoggedIn={true} />      </View>    )  }}

Taro的安装

1.先全局安装@tarojs/cli

$ npm install -g @tarojs/cli$ yarn global add @tarojs/cli

2.之后我们初始化一个名为myApp的项目:

$ taro init myApp

3.然后输入你的配置:

taro初探:使用taro构建微信小程序基础教程插图5
3790386-48803f4402a41530.png

之后等待所有依赖安装完毕。
taro项目目录如下:

├── config                 配置目录|   ├── dev.js             开发时配置|   ├── index.js           默认配置|   └── prod.js            打包时配置├── src                    源码目录|   ├── components         公共组件目录|   ├── pages              页面文件目录|   |   ├── index          index 页面目录|   |   |   ├── banner     页面 index 私有组件|   |   |   ├── index.js   index 页面逻辑|   |   |   └── index.css  index 页面样式|   ├── utils              公共方法库|   ├── app.css            项目总通用样式|   └── app.js             项目入口文件└── package.json

Taro的基本原理

初衷

用React写微信小程序。微信小程序原生方式开发起来太费劲。遂想用React开发微信小程序。

延伸

在React业务代码转微信小程序代码这个最初的需求实现之后,发现依靠同样的转换思路可以适配多端,即从1对1延伸到1对n:

taro初探:使用taro构建微信小程序基础教程插图6
5b307974Na1febb30.jpg

P.S.其中Nerv是一种类React框架,API与React类似
P.S.Taro组件库之所以以微信小程序为标准,也是初衷使然(都做完了不能浪费啊)

一套代转生成多端的思路

想要一份代码通吃n端,无非2种思路:

1.直接从1端向n - 1端转换
2.加一层抽象,从这层抽象转换到n端
Taro也采用了第二种思路,这层抽象就是Taro业务代码:

taro初探:使用taro构建微信小程序基础教程插图7
u=868937013,3662335744&fm=173&app=25&f=JPEG.jpg

核心实现

以微信小程序为例,它由4部分组成:
1.配置(JSON)
2.模板(WXML)
3.样式(WXSS)
4.逻辑(JS)

配置与样式没什么好说的,难点在于模板的转换和逻辑的转换

P.S.ReactNative样式转换另说,也是一个难题,因为RN在选择器、属性名/值及默认值,甚至CSS特性支持程度都存在较大差异

编译转换

要把一份代码A转换成另一份代码B,需要做3件事情:
1.解析代码A生成抽象描述(AST)
2.根据一些映射规则操作AST,生成新的AST
3.根据新的AST生成代码B

taro初探:使用taro构建微信小程序基础教程插图8
taro-compile.jpeg

模板的转换

以小程序为例,把 JSX 语法转换成可以在小程序运行的字符串模板。
输入JSX:

render () {    return (      <View className='index'>        <Button className='add_btn' onClick={this.props.add}>+</Button>        <Button className='dec_btn' onClick={this.props.dec}>-</Button>        <Button className='dec_btn' onClick={this.props.asyncAdd}>async</Button>        <View><Text>{this.props.counter.num}</Text></View>        <View><Text>Hello, World</Text></View>      </View>    )  }

@tarojs/transformer-wx转换,输出微信小程序模板:

<block wx:if="{{$taroCompReady}}">    <view class="index">        <button class="add_btn" bindtap="funPrivateEfvXr">+</button>        <button class="dec_btn" bindtap="funPrivateWnhMJ">-</button>        <button class="dec_btn" bindtap="funPrivateAdUGq">async</button>        <view><text>{{counter.num}}</text>        </view>        <view><text>Hello, World</text>        </view>    </view></block>

逻辑的转换

类似于组件库需要做多端适配,各端能力差异也同样需要适配:

组件库以及端能力都是依靠不同的端做不同实现来抹平差异

运行时框架负责适配各端能力,以支持跑在上面的Taro业务代码,主要有3个作用:

  • 适配组件化方案、配置选项等基础API
  • 适配平台能力相关的API(如网络请求、支付、拍照等)
  • 提供一些应用级的特性,如事件总线(Taro.EventsTaro.eventCenter)、运行环境相关的API(Taro.getEnv()Taro.ENV_TYPE)、UI适配方案(Taro.initPxTransform())等

实现上,@tarojs/taro是API适配的统一入口,编译时分平台替换

平台适配相关的package有6个:

这些API都可以直接使用,不用关心当前平台是否支持,因为运行时框架的适配工作的一部分就是抹平平台能力API差异,例如:

H5 端就无法调用扫码、蓝牙等端能力,各个小程序对页面函数的事件支持的程度也不一样。例如;
页面事件函数各端支持程度如下

方法 作用 微信小程序 百度小程序 字节跳动小程序 支付宝小程序 H5 RN
onPullDownRefresh 页面相关事件处理函数--监听用户下拉动作 ✔️ ✔️ ✔️ ✔️
onReachBottom 页面上拉触底事件的处理函数 ✔️ ✔️ ✔️ ✔️
onShareAppMessage 用户点击右上角转发 ✔️ ✔️ ✔️ ✔️
onPageScroll 页面滚动触发事件的处理函数 ✔️ ✔️ ✔️ ✔️
onTabItemTap 当前是 tab 页时,点击 tab 时触发 ✔️ ✔️ ✔️ ✔️
onResize 页面尺寸改变时触发,详见 响应显示区域变化 ✔️
componentWillPreload 预加载 ✔️
onTitleClick 点击标题触发 ✔️
onOptionMenuClick 点击导航栏额外图标触发 ✔️(基础库 1.3.0)
onPopMenuClick ✔️(基础库 1.3.0)
onPullIntercept 下拉截断时触发 ✔️(基础库 1.11.0)

以上成员方法在 Taro 的页面中同样可以使用,书写同名方法即可,不过需要注意的,目前暂时只有小程序端支持(支持程度如上)这些方法,编译到 H5/RN 端后这些方法均会失效。

采用微信小程序标准,所以这些 API 在 H5 端运行的时候将什么也不做。

同时在业务层区分目标环境,保证这些平台相关的代码仅在预期的目标环境下执行:

  • 编译时:process.env.TARO_ENV
  • 运行时:Taro.getEnv()

例如:

// 分平台调用API或者分平台处理兼容性问题if (process.env.TARO_ENV === 'weapp') {  Taro.textToAudio()}// 分平台使用不同组件<View>  {process.env.TARO_ENV === 'weapp' && <ScrollViewWeapp />}  {process.env.TARO_ENV === 'h5' && <ScrollViewH5 />}</View>

P.S.编译时静态的环境区分足够应对大多数场景了,运行时的环境区分仅备不时之需

项目生命周期之间的匹配

首先一张图看一下小程序的生命周期

taro初探:使用taro构建微信小程序基础教程插图9
5712653-324180d5884ea119.png

1.小程序初始化完成后,页面首次加载触发onLoad,只会触发一次。
2.当小程序进入到后台,先执行页面onHide方法再执行应用onHide方法。
3.当小程序从后台进入到前台,先执行应用onShow方法再执行页面onShow方法。应用生命周期和页面生命周期不是分开的,两者一起进行,相互交叉使用,会用到相同的方法,比如onShow和onHide。
然后看一下react生命周期

taro初探:使用taro构建微信小程序基础教程插图10
ac9f0d1c9cacf270f481aa7aba580f7f (1).jpg

一个例子说明小程序和taro生命周期的映射关系为:

生命周期方法 作用 说明
componentWillMount 程序被载入 对应微信小程序onLaunch
componentDidMount 程序被载入 对应微信小程序onLaunch,在componentWillMount之后执行
componentDidShow 程序展示出来 对应微信小程序onShow
componentDidHide 程序被隐藏 对应微信小程序onHide
componentDidCatchError 错误监听函数 对应微信小程序 onError
componentDidNotFound 页面不存在 对应微信小程序 onPageNotFound

不过当然也包含componentWillUnmout和componentWillReceiveProps等react原始生命周期函数,用来编写自定义组件和h5页面。
在小程序中 ,页面还有一些专属的方法成员,如下:

  1. onPullDownRefresh: 页面相关事件处理函数–监听用户下拉动作
  2. onReachBottom: 页面上拉触底事件的处理函数
  3. onShareAppMessage: 用户点击右上角转发
  4. onPageScroll: 页面滚动触发事件的处理函数
  5. onTabItemTap: 当前是 tab 页时,点击 tab 时触发
  6. componentWillPreload: 预加载,只在微信小程序中可用

设计稿及尺寸单位

在 Taro 中尺寸单位建议使用 px、 百分比 %,Taro 默认会对所有单位进行转换。在 Taro 中书写尺寸按照 1:1 的关系来进行书写,即从设计稿上量的长度 100px,那么尺寸书写就是 100px,当转成微信小程序的时候,尺寸将默认转换为 100rpx,当转成 H5 时将默认转换为以 rem 为单位的值。

如果你希望部分 px 单位不被转换成 rpx 或者 rem ,最简单的做法就是在 px 单位中增加一个大写字母,例如 Px 或者 PX 这样,则会被转换插件忽略。

结合过往的开发经验,Taro 默认以 750px 作为换算尺寸标准,如果设计稿不是以 750px 为标准,则需要在项目配置 config/index.js 中进行设置,例如设计稿尺寸是 640px,则需要修改项目配置 config/index.js 中的 designWidth 配置为 640:

const config = {  projectName: 'myProject',  date: '2018-4-18',  designWidth: 640,  ....}

目前 Taro 支持 750、 640 、 828 三种尺寸设计稿,他们的换算规则如下:

const DEVICE_RATIO = {  '640': 2.34 / 2,  '750': 1,  '828': 1.81 / 2}

建议使用 Taro 时,设计稿以 iPhone 6 750px 作为设计尺寸标准。

API

在编译时,Taro 会帮你对样式做尺寸转换操作,但是如果是在 JS 中书写了行内样式,那么编译时就无法做替换了,针对这种情况,Taro 提供了 API Taro.pxTransform 来做运行时的尺寸转换。

Taro.pxTransform(10) // 小程序:rpx,H5:rem

配置

默认配置会对所有的 px 单位进行转换,有大写字母的 PxPX 则会被忽略。

参数默认值如下:

{  onePxTransform: true,  unitPrecision: 5,  propList: ['*'],  selectorBlackList: [],  replace: true,  mediaQuery: false,  minPixelValue: 0}

Type: Object | Null

onePxTransform (Boolean)

设置 1px 是否需要被转换

unitPrecision (Number)

REM 单位允许的小数位。

propList (Array)

允许转换的属性。

replace (Boolean)

直接替换而不是追加一条进行覆盖。

mediaQuery (Boolean)

允许媒体查询里的 px 单位转换

minPixelValue (Number)

设置一个可被转换的最小 px 值

selectorBlackList (Number)

黑名单里的选择器将会被忽略。

配置规则对应到 config/index.js ,例如:

{  h5: {    publicPath: '/',    staticDirectory: 'static',    module: {      postcss: {        autoprefixer: {          enable: true        },        pxtransform: {          enable: true,          config: {            selectorBlackList: ['body']          }        }      }    }  },  weapp: {    // ...    module: {      postcss: {        pxtransform: {          enable: true,          config: {            selectorBlackList: ['body']          }        }      }    }  }}

忽略

属性

当前忽略单个属性的最简单的方法,就是 px 单位使用大写字母。

 /* `px` is converted to `rem` */.convert {  font-size: 16px; // converted to 1rem} /* `Px` or `PX` is ignored by `postcss-pxtorem` but still accepted by browsers */.ignore {  border: 1Px solid; // ignored  border-width: 2PX; // ignored}

文件

对于头部包含注释 /*postcss-pxtransform disable*/ 的文件,插件不予处理。

一起用Taro做一个demo

文章转载于:https://www.jianshu.com/p/daa8b32518a2

原著是一个有趣的人,若有侵权,请通知删除

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《taro初探:使用taro构建微信小程序基础教程
   

还没有人抢沙发呢~