Skip to content

Commit

Permalink
docs: 补充微信小程序转 Taro 的文档说明
Browse files Browse the repository at this point in the history
  • Loading branch information
yuche committed Dec 6, 2018
1 parent d2eb746 commit fc4ebca
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* [微信小程序原生作用域获取](wx-relations.md)
* [组件的外部样式和全局样式](component-style.md)
* [React Native 端开发流程](react-native.md)
* [微信小程序转 Taro](taroize.md)
* [最佳实践](best-practice.md)
* [组件库](components.md)
* 视图容器
Expand Down
248 changes: 248 additions & 0 deletions docs/taroize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# 微信小程序转 Taro

> `v1.2.0` 开始支持此功能
Taro 可以将你的原生微信小程序应用转换为 Taro 代码,进而你可以通过 `taro build` 的命令将 Taro 代码转换为对应平台的代码,或者对转换后的 Taro 代码进行用 React 的方式进行二次开发。

微信原生小程序转 Taro 的操作非常简单,首先必须安装使用 `npm i -g @tarojs/cli` 安装 Taro 命令行工具,其次在命令行中定位到小程序项目的根目录,根目录中运行:

```bash
$ taro convert
```

即可完成转换。转换后的代码保存在根目录下的 `taroConvert` 文件夹下。

## 二次开发
假设已有一个转换后文件如下:

```javascript
import { View } from '@tarojs/components'
import Taro from '@tarojs/taro'
import withWeapp from '@tarojs/with-weapp'
import './index.scss'

var app = Taro.getApp()

@withWeapp('Page')
class _C extends Taro.Component {
state = {}

componentWillMount(e) {
var orderId = e.id
this.data.orderId = orderId
}

componentDidShow() {
var that = this
Taro.request({
url: 'https://api.it120.cc/' + app.globalData.subDomain + '/order/detail',
data: {
token: Taro.getStorageSync('token'),
id: that.data.orderId
},
success: res => {
Taro.hideLoading()
if (res.data.code != 0) {
Taro.showModal({
title: '错误',
content: res.data.msg,
showCancel: false
})
return
}
that.setData({
orderDetail: res.data.data,
logisticsTraces: res.data.data.logisticsTraces.reverse()
})
}
})
}

config = {
navigationBarTitleText: '物流详情'
}

render() {
const {
orderDetail: orderDetail,
logisticsTraces: logisticsTraces
} = this.state
return (
<View className="container">
<View className="top-sec">
<View className="a-row">
<View className="label">物流单号</View>
<View className="text">{orderDetail.logistics.trackingNumber}</View>
</View>
<View className="a-row">
<View className="label">物流公司</View>
<View className="text">{orderDetail.logistics.shipperName}</View>
</View>
</View>
<View className="sec-wrap">
<View className="details-info">
<View className="line-box" />
{logisticsTraces.map((item, index) => {
return (
<View className="a-row" key={index}>
<View className="dot">
<View
className="active-dot"
hidden={index == 0 ? false : true}
>
<View className="yuan-red" />
</View>
<View
className="default-dot"
hidden={index == 0 ? true : false}
/>
</View>
<View className="info">
<View className="date-box">{item.AcceptTime}</View>
<View className="text">{item.AcceptStation}</View>
</View>
</View>
)
})}
</View>
</View>
</View>
)
}
}

export default _C
```

它看起来就像普通的 Taro 组件,最重要的区别就在于 `@withWeapp()` 这个装饰器,你可以将它理解为转换代码的运行时,`@withWeapp()` 会增加一些原来 Taro 没有方法和属性,例如:

### `this.setData`

转换后的 `this.setData` 的 API 相当于小程序的 `this.setData` 的 polyfill,他和 `this.setState` 最大的区别就在于,`this.setData` 之后 `data` 的数据是同步更新,而渲染是异步更新,而 `setState` 两者都是异步的。

### `this.data``this.properties`

`this.data``this.properties` 相当于 Taro 的 `this.state``this.props` 的 alias,当它们的数据更新时,对应的 `state``props` 也会同步更新。

### 生命周期
Taro 会将原始文件的生命周期钩子函数转换为 Taro 的生命周期,完整对应关系如下:


| Page.onLoad | componentWillMount |
| --: | --: |
| onShow | componentDidShow |
| onHide | componentDidHide |
| onReady | componentDidMount |
| onUnload | componentWillUnmount |
| onError | componentCatchError |
| App.onLaunch | componentWillMount |
| Component.created | componentWillMount |
| attached | componentDidMount |
| ready | componentDidMount |
| detached | componentWillUnmount |
| moved | 保留 |

## 常见问题

### 在小程序 IDE 显示 `_createData` 错误

这个错误通常是由于原始代码的初始 `data` 中没有对应的数据,后来通过 `this.setData` 补充数据造成的。在 Taro 中推荐不管是 `state(data)` 还是 `properties(props)` 都要设置一个默认值。你可以在类构造器或修改原始代码提供一个默认值解决这个问题,这也应该是编写代码的最佳实践。

### 转换 `wxParse` 报错不存在文件

这是由于 `wxParse` 的源码使用了一个[不存在的 `template` ](https://github.com/icindy/wxParse/issues/255)声明造成的。你可以修改 `wxParse` 的源码文件 `wxParse.wxml` 49 行到 129 行:

```html
<!--循环模版-->
<template name="wxParse0">
<!--<template is="wxParse1" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</view>
</view>
</view>
</block>

<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}" />
</block>

<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}" />
</block>

<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</view>
</block>
<block wx:elif="{{item.tag == 'table'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</view>
</block>

<block wx:elif="{{item.tag == 'br'}}">
<template is="WxParseBr"></template>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</view>
</block>

<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}" />
</block>
</view>

</block>

<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}" />
</block>

</template>
```

把所有 `<template is="wxParse1" data="{{item}}" />` 修改为 `<template is="wxParse0" data="{{item}}" />` 再运行 `taro convert` 即可。这样修改之后还会取消原来 `wxParse` 只能处理 11 级 HTML 嵌套的问题,理论上内存不爆栈可以处理无限级 HTML 嵌套。

### 不支持 `relations``Behavior`

目前转换暂只支持转换 `Page``Component``App` 三种构造器创造的小程序组件实例。 `relations``Behavior` 在其他许多小程序端中还没有对应的实现,我们认为实现这两个功能意义不大。

### 转换 wepy 文件不成功

目前只能支持转换使用原生微信小程序开发的应用。

0 comments on commit fc4ebca

Please sign in to comment.