diff --git a/docs/config-detail.md b/docs/config-detail.md
index 374f770e8690..3676cecaad8d 100644
--- a/docs/config-detail.md
+++ b/docs/config-detail.md
@@ -35,7 +35,7 @@ title: 编译配置详情
配置方式可参考 [Webpack DefinePlugin](https://webpack.js.org/plugins/define-plugin/),例如:
-```js
+```js title="/config/index.js"
module.exports = {
// ...
defineConstants: {
@@ -110,7 +110,7 @@ import projectConfig from '@/project'
**config/dev.js**:
-```jsx
+```jsx title="/config/dev.js"
module.exports = {
// ...
env: {
@@ -121,7 +121,7 @@ module.exports = {
**config/prod.js**:
-```jsx
+```jsx title="config/prod.js"
module.exports = {
// ...
env: {
diff --git a/docs/config.md b/docs/config.md
index 33b769ecd449..b29c7b033e60 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -10,7 +10,7 @@ title: 编译配置
## index.js —— 通用配置
-```js
+```js title="/config/index.js"
const config = {
// 项目名称
projectName: 'Awesome Next',
diff --git a/docs/convert-to-react.md b/docs/convert-to-react.md
new file mode 100644
index 000000000000..f09cf129acb2
--- /dev/null
+++ b/docs/convert-to-react.md
@@ -0,0 +1,72 @@
+---
+title: 转换成 React
+---
+
+## 二次开发
+
+原生小程序代码:
+
+```jsx
+Page({
+ data: {
+ text: 'Hello World'
+ }
+})
+
+
+ {{ text }}
+
+```
+
+转换后:
+
+```javascript
+import { Block, View } from '@tarojs/components'
+import React from 'react'
+import Taro from '@tarojs/taro'
+import withWeapp from '@tarojs/with-weapp'
+import Title from '../../components/title/index'
+import './index.scss'
+
+@withWeapp({
+ data: {
+ text: 'Hello World'
+ }
+})
+class _C extends React.Component {
+ render() {
+ const { text } = this.data
+ return {text}
+ }
+}
+
+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 的生命周期,完整对应关系如下:
+
+|小程序生命周期|Taro 生命周期|
+| :-- | :-- |
+| onShow | componentDidShow |
+| onHide | componentDidHide |
+| App.onLaunch | onLaunch |
+| Page.onLoad | onLoad |
+| Page.onReady | onReady |
+| Page.onUnload | componentWillUnmount |
+| Component.created | componentWillMount |
+| Component.attached | componentDidMount |
+| Component.ready | Page.onReady |
+| Component.detached | componentWillUnmount |
+
diff --git a/docs/css-in-js.md b/docs/css-in-js.md
index 68755d112416..00a2edb8c26b 100644
--- a/docs/css-in-js.md
+++ b/docs/css-in-js.md
@@ -16,7 +16,7 @@ $ npm i linaria
其次配置项目根目录的 `babel.config.js`:
-```js
+```js title="babel.config.js"
module.exports = {
presets: [
['taro', {
@@ -30,7 +30,7 @@ module.exports = {
之后配置 `config/index.js`
-```js
+```js title="config/index.js"
const config = {
mini: {
webpackChain(chain, webpack) {
@@ -49,7 +49,7 @@ const config = {
最后在项目根目录新建 `linaria.config.js`
-```js
+```js title="linaria.config.js"
// linaria 配置详见 https://github.com/callstack/linaria/blob/master/docs/CONFIGURATION.md#options
module.exports = {
rules: [
diff --git a/docs/css-modules.md b/docs/css-modules.md
index 5768e96f0b51..bbee1769788a 100644
--- a/docs/css-modules.md
+++ b/docs/css-modules.md
@@ -8,7 +8,7 @@ Taro 中内置了 [CSS Modules](https://github.com/css-modules/css-modules) 的
小程序端开启
-```js
+```js title="config/index.js"
weapp: {
module: {
postcss: {
@@ -27,7 +27,7 @@ weapp: {
H5 端开启
-```js
+```js title="config/index.js"
h5: {
module: {
postcss: {
diff --git a/docs/debug-config.md b/docs/debug-config.md
index 603893a8a3d5..b37e194fd3e5 100644
--- a/docs/debug-config.md
+++ b/docs/debug-config.md
@@ -43,7 +43,7 @@ yarn global add rollup
launch.json 有以下预设配置:
-```json
+```json title="launch.json"
{
// ...
"configurations": [
@@ -83,7 +83,7 @@ launch.json 有以下预设配置:
可以这样配置 launch.json:
-```json
+```json title="launch.json"
{
// ...
"configurations": [
@@ -108,7 +108,7 @@ launch.json 有以下预设配置:
可以这样配置 launch.json:
-```json
+```json title="launch.json"
{
// ...
"configurations": [
diff --git a/docs/envs-debug.md b/docs/envs-debug.md
index 6d613d3a7286..f882f09b1b7b 100644
--- a/docs/envs-debug.md
+++ b/docs/envs-debug.md
@@ -3,7 +3,8 @@ title: 多端同步调试
---
从 1.3.5 版本开始,可以在 dist 目录下创建一个与编译的目标平台名同名的目录,并将结果放在这个目录下,例如编译到微信小程序,最终结果是在 dist/weapp 目录下,这样做的好处是,各个平台使用独立的目录互不影响,从而达到多端同步调试的目的,在 `config/index.js` 配置如下:
-```
+
+```js title="/config/index.js"
outputRoot: `dist/${process.env.TARO_ENV}`
```
diff --git a/docs/envs.md b/docs/envs.md
index 2cf44bb91071..6dd8e972507c 100644
--- a/docs/envs.md
+++ b/docs/envs.md
@@ -81,7 +81,7 @@ import Test from '../../components/test'
增加 `set_title.h5.js`,代码如下
-```js
+```js title="set_title.h5.js"
export default function setTitle (title) {
document.title = title
}
@@ -89,7 +89,7 @@ export default function setTitle (title) {
增加 `set_title.weapp.js`,代码如下
-```js
+```js title="set_title.weapp.js"
import Taro from '@tarojs/taro'
export default function setTitle (title) {
Taro.setNavigationBarTitle({
@@ -145,7 +145,7 @@ Taro 3 里的多端文件由 [MultiPlatformPlugin](https://github.com/NervJS/tar
假如我们有一个 npm 包名叫 @taro-mobile,需要解析里面的多端文件,可以在 taro 的配置文件中这样修改 MultiPlatformPlugin 的配置:
-```js
+```js title="/config/index.js"
// mini 也可改为 h5,分别对应小程序与 h5 端配置
mini: {
webpackChain (chain) {
diff --git a/docs/mini-third-party.md b/docs/mini-third-party.md
index 2e7cda740928..bff39f906793 100644
--- a/docs/mini-third-party.md
+++ b/docs/mini-third-party.md
@@ -18,8 +18,7 @@ Taro 支持使用小程序的第三方组件和插件,使用方式也异常的
> 注意:Taro3 中没有自定义组件,组件是没有配置文件的。usingComponents 必须配置在“页面”的配置文件中。
-```js
-// page.config.js
+```js {2} title="page.config.js"
export default {
usingComponents: {
// 定义需要引入的第三方组件
@@ -32,8 +31,7 @@ export default {
2. JSX 中引用
-```jsx
-// page.js
+```jsx {14} title="page.js"
import React, { Component } from 'react'
import { View } from '@tarojs/components'
@@ -83,8 +81,7 @@ page.selectComponent('#mychart-dom-area')
使用插件前,使用者要在 `app.confg.js` 的配置中声明需要使用的插件,例如
-```jsx
-// app.config.js
+```jsx title="app.config.js"
export default {
plugins: {
myPlugin: {
diff --git a/docs/miniprogram-plugin.md b/docs/miniprogram-plugin.md
index d6b42783f42d..485c1164bca5 100644
--- a/docs/miniprogram-plugin.md
+++ b/docs/miniprogram-plugin.md
@@ -50,7 +50,7 @@ taro build --plugin weapp --watch
plugin.json 的 **pages** 字段加入页面插件路径:
-```json
+```json title="plugin.json"
{
"pages": {
"list": "pages/list/list"
@@ -60,7 +60,7 @@ plugin.json 的 **pages** 字段加入页面插件路径:
页面使用路径: **plugin://[app.js 中注册的插件名]/[plugin.json 中注册的页面名]** 进行跳转。
-```jsx
+```jsx {1}
Go to pages/list!
@@ -70,7 +70,7 @@ plugin.json 的 **pages** 字段加入页面插件路径:
plugin.json 的 **publicComponents** 字段加入组件插件路径:
-```json
+```json title="plugin.json"
{
"publicComponents": {
"avatar": "components/avatar/avatar"
@@ -80,7 +80,7 @@ plugin.json 的 **publicComponents** 字段加入组件插件路径:
在页面配置 config.usingComponents 中配置好插件名和插件路径(**plugin://[app.js 中注册的插件名]/[plugin.json 中注册的组件名]**):
-```jsx
+```jsx {4}
export default class Index extends Component {
config = {
usingComponents: {
@@ -114,7 +114,7 @@ const extraProps = {
plugin.json 的 **main** 字段加入接口插件路径:
-```json
+```json title="plugin.json"
{
"main": "index.js"
}
diff --git a/docs/nerv.md b/docs/nerv.md
index 0536b3c0040b..f73607c863bb 100644
--- a/docs/nerv.md
+++ b/docs/nerv.md
@@ -8,7 +8,7 @@ title: Nerv
在使用第三方 React 库时,需要在[配置文件](config-detail.md#miniwebpackchain) `webpack.resolve.alias`,把 `react` 和 `react-dom` 映射到 `nervjs`:
-```js
+```js title="/config/index.js"
{
webpackChain (chain, webpack) {
chain.merge({
diff --git a/docs/platform-plugin-base.md b/docs/platform-plugin-base.md
index 906b319fc034..a797b2e499ca 100644
--- a/docs/platform-plugin-base.md
+++ b/docs/platform-plugin-base.md
@@ -6,8 +6,7 @@ title: TaroPlatformBase
例如我们创建一个微信小程序平台:
-```js
-// program.ts
+```js title="program.ts"
import { TaroPlatformBase } from '@tarojs/service'
export default class Weapp extends TaroPlatformBase {
// ...
@@ -184,8 +183,7 @@ runner(options)
### 1. 继承基类
-```js
-// program.ts
+```js title="program.ts"
import { TaroPlatformBase } from '@tarojs/service'
class Weapp extends TaroPlatformBase {
@@ -234,8 +232,7 @@ class Weapp extends TaroPlatformBase {
规范:
-```js
-//components.ts
+```js title="components.ts"
import { singleQuote } from '@tarojs/shared'
export const components = {
@@ -319,8 +316,7 @@ internalComponent = {
除了借助 `template.mergeComponents` 进行合并,我们也可以直接修改 `template.internalComponents`。
-```js
-// program.ts
+```js title="program.ts"
class Weapp extends TaroPlatformBase {
modifyComponents () {
// 删除 Slider 组件里的一些属性
@@ -376,8 +372,7 @@ class Weapp extends TaroPlatformBase {
我们创建的平台类需要编写一个对外的接口,在其中对编译流程进行设计,最终目标是调用 `@tarojs/mini-runner` 驱动 **Webpack** 开启编译。
-```js
-// program.ts
+```js title="program.ts"
class Weapp extends TaroPlatformBase {
// ...
async start () {
diff --git a/docs/platform-plugin-how.md b/docs/platform-plugin-how.md
index 988a719cdc65..12f0ed19ac63 100644
--- a/docs/platform-plugin-how.md
+++ b/docs/platform-plugin-how.md
@@ -41,8 +41,7 @@ title: 编写端平台插件
首先我们需要编写一个 Taro 插件来注册我们的编译平台,如:
-```js
-// index.ts
+```js title="index.ts"
export default (ctx) => {
ctx.registerPlatform({
name: 'weapp',
@@ -99,8 +98,7 @@ Taro 小程序相关配置默认放在 `mini` 字段下,因此一般情况配
然后在插件入口函数中调用上述自定义平台类的编译接口:
-```js
-// index.ts
+```js title="index.ts"
import Weapp from './program'
export default (ctx) => {
@@ -221,8 +219,7 @@ export function initNativeApi (taro) {
当前扩展的小程序平台如果需要额外新增 API,建议使用一个 `apis-list.ts` 文件维护:
-```js
-// apis-list.ts
+```js title="apis-list.ts"
// 微信小程序部分扩展 API
export const _onAndSyncApis = new Set([
'getAccountInfoSync'
@@ -279,8 +276,7 @@ function processApis (taro) {
注意,Taro 相关的包需要配置 `external`,以免重复打包:
-```js
-// rollup.config.js
+```js title="rollup.config.js"
{
external: ['@tarojs/shared', '@tarojs/service']
}
@@ -292,8 +288,7 @@ Taro 核心库维护的类型可能没有包括当前插件新增的组件和 AP
创建一个类型定义文件:
-```ts
-// types/shims-iot.d.ts
+```ts title="types/shims-iot.d.ts"
// 为支付宝 IOT 小程序拓展新增的 API 和组件定义
import { ComponentType } from 'react'
import Taro from '@tarojs/taro'
@@ -319,7 +314,6 @@ declare module '@tarojs/components' {
开发者在类型定义文件中引入此文件即可:
-```ts
-// global.d.ts
+```ts title="global.d.ts"
///
```
diff --git a/docs/plugin.md b/docs/plugin.md
index 04788fe373e2..ea8bd409a9e2 100644
--- a/docs/plugin.md
+++ b/docs/plugin.md
@@ -20,7 +20,7 @@ Taro 提供了一些官方插件
`plugins` 字段取值为一个数组,配置方式如下:
-```js
+```js title="/config/index.js"
const config = {
plugins: [
// 引入 npm 安装的插件
@@ -46,7 +46,7 @@ const config = {
配置[编译配置](./config-detail.md)中的 `presets` 字段,如下。
-```js
+```js title="/config/index.js"
const config = {
presets: [
// 引入 npm 安装的插件集
diff --git a/docs/prerender.md b/docs/prerender.md
index 4521678b86d2..ed62c1854835 100644
--- a/docs/prerender.md
+++ b/docs/prerender.md
@@ -18,8 +18,7 @@ Taro Next 在一个页面加载时需要经历以下步骤:
使用 Prerender 非常简单,你可以找到项目根目录下的 `config` 文件夹,根据你的项目情况更改 `index.js`/`dev.js`/`prod.js` 三者中的任意一个[项目配置](./config.md),在编译时 Taro CLI 会根据你的配置自动启动 prerender:
-```js
-// /project/config/prod.js
+```js title="/config/index.js 或 /config/dev.js 或 /config/prod.js "
const config = {
...
mini: {
diff --git a/docs/redux.md b/docs/redux.md
index 5ded4e3d36a9..d1bf2f9f482e 100644
--- a/docs/redux.md
+++ b/docs/redux.md
@@ -14,8 +14,7 @@ $ npm install --save redux react-redux redux-thunk redux-logger
随后可以在项目 `src` 目录下新增一个 `store` 目录,在目录下增加 `index.js` 文件用来配置 `store`,按自己喜好设置 `redux` 的中间件,例如下面例子中使用 `redux-thunk` 和 `redux-logger` 这两个中间件
-```jsx
-// src/store/index.js
+```jsx title="src/store/index.js"
import { createStore, applyMiddleware, compose } from 'redux'
import thunkMiddleware from 'redux-thunk'
import rootReducer from '../reducers'
@@ -48,8 +47,7 @@ export default function configStore () {
接下来在项目入口文件 `app.js` 中使用 `redux` 中提供的 `Provider` 组件将前面写好的 `store` 接入应用中
-```jsx
-// src/app.js
+```jsx title="src/app.js"
import React, { Component } from 'react'
import { Provider } from 'react-redux'
@@ -93,16 +91,14 @@ export default App
新增 `action type`
-```jsx
-// src/constants/counter.js
+```jsx title="src/constants/counter.js"
export const ADD = 'ADD'
export const MINUS = 'MINUS'
```
新增 `reducer` 处理
-```jsx
-// src/reducers/counter.js
+```jsx title="src/reducers/counter.js"
import { ADD, MINUS } from '../constants/counter'
const INITIAL_STATE = {
@@ -127,8 +123,7 @@ export default function counter (state = INITIAL_STATE, action) {
}
```
-```jsx
-// src/reducers/index.js
+```jsx title="src/reducers/index.js"
import { combineReducers } from 'redux'
import counter from './counter'
@@ -140,8 +135,7 @@ export default combineReducers({
新增 `action` 处理
-```jsx
-// src/actions/counter.js
+```jsx title="src/actions/counter.js"
import {
ADD,
MINUS
@@ -171,8 +165,7 @@ export function asyncAdd () {
最后,我们可以在页面(或者组件)中进行使用,我们将通过 `redux` 提供的 `connect` 方法将 `redux` 与我们的页面进行连接
-```jsx
-// src/pages/index/index.js
+```jsx title="src/pages/index/index.js"
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { View, Button, Text } from '@tarojs/components'
diff --git a/docs/size.md b/docs/size.md
index 79d97d12d89a..a95afcfe6b00 100644
--- a/docs/size.md
+++ b/docs/size.md
@@ -8,7 +8,7 @@ title: 设计稿及尺寸单位
结合过往的开发经验,Taro 默认以 `750px` 作为换算尺寸标准,如果设计稿不是以 `750px` 为标准,则需要在项目配置 `config/index.js` 中进行设置,例如设计稿尺寸是 `640px`,则需要修改项目配置 `config/index.js` 中的 `designWidth` 配置为 `640`:
-```jsx
+```jsx title="/config/index.js"
const config = {
projectName: 'myProject',
date: '2018-4-18',
@@ -108,7 +108,7 @@ REM 单位允许的小数位。
配置规则对应到 `config/index.js` ,例如:
-```js
+```js {9-14,20-25} title="/config/index.js"
{
h5: {
publicPath: '/',
diff --git a/docs/static-reference.md b/docs/static-reference.md
index 0884d311cabc..aa9533ec9246 100644
--- a/docs/static-reference.md
+++ b/docs/static-reference.md
@@ -70,7 +70,7 @@ Taro 默认会对 `1kb` 大小以下的资源进行转换,如果需要修改
具体配置如下
-```javascript
+```js title="/config/index.js"
// 小程序端样式引用本地资源内联
url: {
enable: true,
diff --git a/docs/taroize-troubleshooting.md b/docs/taroize-troubleshooting.md
new file mode 100644
index 000000000000..6aa3be0c6c3c
--- /dev/null
+++ b/docs/taroize-troubleshooting.md
@@ -0,0 +1,291 @@
+---
+title: Troubleshooting
+---
+
+## 不支持的小程序特性
+
+### 入口 App 对象
+
+|属性|说明|
+|:--|:--|
+|onError||
+|onPageNotFound||
+|onUnhandledRejection||
+|onThemeChange||
+
+### 页面 Page 对象
+
+|属性|说明|
+|:--|:--|
+|selectComponent|建议使用 React ref 重构|
+|selectAllComponents|建议使用 React ref 重构|
+|selectOwnerComponent|建议使用 React ref 重构|
+|groupSetData||
+
+### 自定义组件
+
+|属性|说明|
+|:--|:--|
+|moved||
+|externalClasses|Taro 3 不存在自定义组件,建议规范类名或使用 CSS Module 代替|
+|relations||
+|options||
+|definitionFilter||
+
+### wxml 语法
+
+|属性|说明|
+|:--|:--|
+|循环|[部分语法有限制]|
+|事件|[部分语法有限制](./taroize-troubleshooting#2-事件)|
+|引用|[部分语法有限制](./taroize-troubleshooting#16-include-里不支持使用-template)|
+|wxs|[部分语法有限制](./taroize-troubleshooting#15-不支持-wxs-里的-getregexp-方法)|
+
+## 关键问题
+
+### 1. 没有处理基类
+
+原生开发中,常常会把 App、Page、Component 构造对象的公共逻辑整合到基类中。
+
+如 **Vant-weapp** 中:
+
+```js
+// 组件
+VantComponent({
+ data: {}
+})
+// 基类
+function VantComponent(vantOptions = {}) {
+ // 整合组件独有配置 vantOptions 和公共配置到最终的配置对象 options 中
+ // ...
+
+ // 调用小程序的 Component 方法构造自定义组件
+ Component(options);
+}
+```
+
+Taro 在编译时只能识别出入口、页面、组件文件中存在的 `App()`、`Page()`、`Component()` 调用,使用基类对配置封装后就不存在这些调用。因此编译后的 `withWeapp` 获得的参数是 `{}`。
+
+```js
+VantComponent({
+ data: {}
+})
+// withWeapp 中应该传入小程序配置对象
+@withWeapp({})
+class _C extends React.Component {}
+```
+
+因此我们需要手动修改:
+
+```js
+// 基类
+function VantComponent(vantOptions = {}) {
+ // 整合组件独有配置 vantOptions 和公共配置到最终的配置对象 options 中
+ // ...
+
+ // 调用小程序的 Component 方法构造自定义组件
+ // Component(options);
+
+ // 1. 基类直接返回整合后的 options
+ return options
+}
+```
+
+
+```js
+// 2. 把基类创建的配置传入 withWeapp:
+const options = VantComponent({
+ data: {}
+})
+@withWeapp(options)
+class _C extends React.Component {}
+```
+
+### 2. 样式作用域
+
+微信小程序中的自定义组件,转换后会生成一个 Taro 中的 React/Vue 组件。
+
+但是 Taro 中使用 React/Vue 开发的组件,编译到小程序平台时,并不会生成对应的小程序自定义组件。
+
+**因此微信小程序自定义组件的样式隔离特性,在转换为 Taro 后就会丢失。**
+
+#### 解决办法:
+
+1. 修改冲突的选择器。
+2. 使用 CSS Modules 进行改写。
+
+## 常见问题
+
+### 1. wxml 语法转换问题
+
+把 `wxml` 转换为 `JSX` 是通过操作 `AST` 实现的,有一些写法可能没有考虑到,或难以适配,从而导致报错。
+
+以下是一些已知问题,需要手动修复:
+
+#### 1.1 组件同时使用 `wx:for` 和 `wx:if` 语句时转换错误
+
+当组件上同时使用了 `wx:for` 和 `wx:if` 语句,并且使用了当前**循环元素 item** 或**循环下标 index** 做判断条件时,转换后会报错。
+
+例如:
+
+```jsx
+// 转换前(注意判断条件使用了循环下标 index):
+
+ objectArray item: {{item.id}}
+
+```
+
+```jsx
+// 转换后:
+{index % 2 !== 0 && (
+
+ {objectArray.map((item, index) => {
+ return (
+
+ {'objectArray item: ' + item.id}
+
+ )
+ })}
+
+)}
+```
+
+上例可见,对于条件语句的转换,目前的处理会把条件提取到组件外部。但是如果条件使用了 `item` 或 `index` 时,这样的提取逻辑会导致**变量未定义**的报错。
+
+暂时可以通过手动修复解决:
+
+方法一,修改**编译前**的代码,把循环和条件语句拆开到两个组件中:
+
+```jsx
+
+
+ objectArray item: {{item.id}}
+
+
+```
+
+方法二,修改**编译后**的代码,把条件判断放进循环体中:
+
+```jsx
+
+ {objectArray.map((item, index) => {
+ return (
+
+ {index % 2 !== 0 && {'objectArray item: ' + item.id}}
+
+ )
+ })}
+
+```
+
+#### 1.2 根元素不能含有 `hidden` 属性。
+
+#### 1.3 编译时报错:SyntaxError: Unexpected token
+
+尖括号 “<” 右侧需要留一个空格,[#4243](https://github.com/NervJS/taro/issues/4243)
+
+##### 解决办法:
+
+检查是否存在以下写法:
+
+```jsx
+{{a <4? "1": "2"}}
+```
+
+改为:
+
+```jsx
+{{a < 4? "1": "2"}}
+```
+
+#### 1.4 运行时报错:ReferenceError: item is not defined
+
+查看编译后的 JSX,是否因为漏了从 `this.data` 中取出变量,如:
+
+```
+// 下面的代码没有引用 item
+const { a, b, c } = this.data
+```
+
+##### 解决办法:
+
+`this.data` 中的变量名,不要和用于指定数组当前下标的变量名,默认值为 `item`,或由 `wx:for-index` 具体指定的变量名相同。
+
+
+#### 1.5 不支持 WXS 里的 GetRegExp 方法
+
+使用 `RegExp` 构造正则表达式。
+
+#### 1.6 `` 里不支持使用 ``
+
+#### 1.7 template 里暂不支持使用 catch 事件
+
+### 2. 事件
+
+* 事件不支持绑定字符串。
+* `catchtouchmove` 转换后只能停止回调函数的冒泡,不能阻止滚动穿透。如要阻止滚动穿透,可以手动给编译后的 `View` 组件加上 `catchMove` 属性。
+* 不支持事件捕获阶段。
+* 不支持使用 WXS 函数响应事件。
+* 不支持互斥事件绑定 `mut-bind`。
+* 不支持 `mark` 来识别具体触发事件的 target 节点。
+
+### 3. CommonJS 和 ES 模块化语法不能混用
+
+可能遇到的报错信息:
+
+* Cannot assign to read only property 'exports' of object
+* export '[something]' (imported as '[name]') was not found in '[somePath]'
+
+在使用到小程序 API 的地方,Taro 会把 `wx.api()` 转换为 `Taro.api()`,同时在文件的头部加上 `import Taro from '@tarjs/taro`。
+
+如果此文件原本是使用 **CommonJS** 组织模块,可能会出现问题,需要手动修复。
+
+### 4. selectorQuery API 获取不到 DOM
+
+1. 一定要在 `onReady`、`ready` 生命周期中才能调用小程序 API 获取 DOM。
+2. 不需要调用 `.in(this)` 方法。
+
+### 5. Image 没有处理动态拼接的 src
+
+Taro 会对 `Image` 组件的 src 进行处理:
+
+```jsx
+// 转换前:
+
+// 转换后:
+
+```
+
+但如果 `src` 是动态拼接的字符串,则需要手动修改:
+
+```jsx
+// 转换前:
+
+// 转换后:
+
+// 手动修改,图片也需要手动拷贝到 taroConert/src 对应目录下:
+
+```
+
+### 6. require 的参数不能是变量
+
+可能遇到的报错信息:
+
+* The "path" argument must be of type string. Received type undefined
+
+不支持转换以下写法,[#4749](https://github.com/NervJS/taro/issues/4749):
+
+```js
+var pathTest = './test.js'
+var test = require(pathTest)
+```
+
+Taro 目前只能转换 `require` 字符串的写法。
+
+### 7. 没有处理 export from 语法
+
+暂时手动处理,[#5131](https://github.com/NervJS/taro/issues/5131)。
+
+### 8. Issues
+
+反向转换的更多问题,请查阅 Taroize 相关 [Issues](https://github.com/NervJS/taro/issues?q=is%3Aopen+is%3Aissue+label%3AA-taroize)。
diff --git a/docs/taroize.md b/docs/taroize.md
index 1653ac7433d8..59f0af756af1 100644
--- a/docs/taroize.md
+++ b/docs/taroize.md
@@ -2,250 +2,34 @@
title: 微信小程序转 Taro
---
-> 自 `v1.2.0` 开始支持此功能
+Taro 可以把**原生微信小程序应用转换为 Taro 项目**,从而使项目成为多端应用。
-Taro 可以将你的原生微信小程序应用转换为 Taro 代码,进而你可以通过 `taro build` 的命令将 Taro 代码转换为对应平台的代码,或者对转换后的 Taro 代码进行用 React 的方式进行二次开发。
+转换后的代码可读性高,能够继续使用 **React**(将来支持转换为 **Vue**)进行二次开发。
-微信原生小程序转 Taro 的操作非常简单,首先必须安装使用 `npm i -g @tarojs/cli` 安装 Taro 命令行工具,其次在命令行中定位到小程序项目的根目录,根目录中运行:
+### 反向转换步骤
+
+1. 安装 Taro 命令行工具:
```bash
-$ taro convert
+$ npm i -g @tarojs/cli
```
-即可完成转换。转换后的代码保存在根目录下的 `taroConvert` 文件夹下。你需要定位到 `taroConvert` 目录执行 `npm install` 命令之后就可以使用 `taro build` 命令编译到对应平台的代码。
-
-## 二次开发
-
-假设已有一个转换后文件如下:
-
-```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: '物流详情'
- }
+2. 在微信小程序项目的根目录中运行 `convert` 命令进行转换:
- render() {
- const {
- orderDetail: orderDetail,
- logisticsTraces: logisticsTraces
- } = this.state
- return (
-
-
-
- 物流单号
- {orderDetail.logistics.trackingNumber}
-
-
- 物流公司
- {orderDetail.logistics.shipperName}
-
-
-
-
-
- {logisticsTraces.map((item, index) => {
- return (
-
-
-
-
-
-
-
-
- {item.AcceptTime}
- {item.AcceptStation}
-
-
- )
- })}
-
-
-
- )
- }
-}
-
-export default _C
+```bash
+# 转换后的代码保存在根目录下的 `taroConvert` 文件夹下
+$ taro convert
```
-它看起来就像普通的 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 | componentDidCatchError |
-| App.onLaunch | componentWillMount |
-| Component.created | componentWillMount |
-| attached | componentDidMount |
-| ready | componentDidMount |
-| detached | componentWillUnmount |
-| moved | 保留 |
+3. 进入 `taroConvert` 目录,安装依赖:
-## 常见问题
-
-### 在小程序 IDE 显示 `_createData` 错误
-
-这个错误通常是由于原始代码的初始 `data` 中没有对应的数据,后来通过 `this.setData` 补充数据造成的。在 Taro 中推荐不管是 `state(data)` 还是 `properties(props)` 都要设置一个默认值。你可以在类构造器或修改原始代码提供一个默认值解决这个问题,这也应该是编写代码的最佳实践。
-
-### 转换 `wxParse` 报错不存在文件
-
-这是由于 `wxParse` 的源码使用了一个[不存在的 `template`](https://github.com/icindy/wxParse/issues/255) 声明造成的。你可以修改 `wxParse` 的源码文件 `wxParse.wxml` 134 行到 207 行:
-
-```html
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+```bash
+$ cd taroConvert
+$ npm install
```
-把 `` 的模板内所有 `` 修改为 `` 再运行 `taro convert` 即可。这样修改之后还会取消原来 `wxParse` 只能处理 11 级 HTML 嵌套的问题,理论上内存不爆栈可以处理无限级 HTML 嵌套。
-
-### 不支持 `relations` 和 `Behavior`
+4. 运行 `build` 命令,把项目编译到任意平台:
-目前转换暂只支持转换 `Page`、`Component` 、`App` 三种构造器创造的小程序组件实例。 `relations` 和 `Behavior` 在其他许多小程序端中还没有对应的实现,我们认为实现这两个功能意义不大。
-
-### 转换 wepy 文件不成功
-
-目前只能支持转换使用原生微信小程序开发的应用。
+```bash
+$ taro build --type [platform]
+```
diff --git a/docs/template.md b/docs/template.md
index 7f904c642cf8..5880ceff125b 100644
--- a/docs/template.md
+++ b/docs/template.md
@@ -87,7 +87,7 @@ zip 包解压出单文件夹,文件夹内包含若干模板。
开发者可以在模板根目录加入 **template_creator.js** 文件,文件对外 exports 包含 handler 与 basePageFiles 字段的对象:
-```js
+```js {5,16} title="template_creator.js"
function createWhenTs (params) {
return params.typescript ? true : false
}
@@ -134,8 +134,7 @@ module.exports = {
##### 例子
-```ejs
-// index.js
+```ejs title="index.js"
<%if (typescript) {-%>
import Taro, { Component, Config } from '@tarojs/taro'
<%} else { -%>
@@ -197,8 +196,7 @@ return: boolean/object
当用户选择了使用 typescript 时,才生成 **global.d.ts** 和 **tsconfig.json** 文件。
-```js
-// template_creator.js
+```js title="template_creator.js"
function createWhenTs (params) {
return params.typescript ? true : false
}
@@ -221,8 +219,7 @@ basePageFiles 告诉 CLI,当用户使用 `taro create` 命令创建页面时
当用户使用命令 `taro create --page=detail` 时,会创建 **/src/pages/detail/detail.jsx** 与 **/src/pages/detail/detail.css** 两个文件。
-```js
-// template_creator.js
+```js title="template_creator.js"
const handler = {
'/src/pages/index/index.jsx' ({ pageName }) {
return { setPageName: `/src/pages/${pageName}/${pageName}.jsx` }
diff --git a/docs/tutorial.md b/docs/tutorial.md
index 542886c0aeb2..24484dce19f7 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -73,8 +73,7 @@ Taro 中全局配置所包含的配置项及各端支持程度如下
则需要在入口文件配置中写
-```jsx
-// app.config.js
+```jsx title="app.config.js"
export default {
pages: [
'pages/index/index',
@@ -124,8 +123,7 @@ export default {
配置示例如下:
-```jsx
-// app.config.js
+```jsx title="app.config.js"
export default {
pages: [
'pages/index/index',
diff --git a/sidebars.js b/sidebars.js
index 9b0fac2b2b53..2934da0fa06b 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -31,6 +31,15 @@ module.exports = {
'virtual-list',
'mini-third-party',
'hybrid',
+ {
+ label: '反向转换',
+ type: 'category',
+ items: [
+ 'taroize',
+ 'convert-to-react',
+ 'taroize-troubleshooting'
+ ]
+ },
{
label: '扩展编译平台',
type: 'category',
diff --git a/versioned_docs/version-3.x/config-detail.md b/versioned_docs/version-3.x/config-detail.md
index 374f770e8690..3676cecaad8d 100644
--- a/versioned_docs/version-3.x/config-detail.md
+++ b/versioned_docs/version-3.x/config-detail.md
@@ -35,7 +35,7 @@ title: 编译配置详情
配置方式可参考 [Webpack DefinePlugin](https://webpack.js.org/plugins/define-plugin/),例如:
-```js
+```js title="/config/index.js"
module.exports = {
// ...
defineConstants: {
@@ -110,7 +110,7 @@ import projectConfig from '@/project'
**config/dev.js**:
-```jsx
+```jsx title="/config/dev.js"
module.exports = {
// ...
env: {
@@ -121,7 +121,7 @@ module.exports = {
**config/prod.js**:
-```jsx
+```jsx title="config/prod.js"
module.exports = {
// ...
env: {
diff --git a/versioned_docs/version-3.x/config.md b/versioned_docs/version-3.x/config.md
index 33b769ecd449..b29c7b033e60 100644
--- a/versioned_docs/version-3.x/config.md
+++ b/versioned_docs/version-3.x/config.md
@@ -10,7 +10,7 @@ title: 编译配置
## index.js —— 通用配置
-```js
+```js title="/config/index.js"
const config = {
// 项目名称
projectName: 'Awesome Next',
diff --git a/versioned_docs/version-3.x/convert-to-react.md b/versioned_docs/version-3.x/convert-to-react.md
new file mode 100644
index 000000000000..9051e19f4351
--- /dev/null
+++ b/versioned_docs/version-3.x/convert-to-react.md
@@ -0,0 +1,76 @@
+---
+title: 转换成 React
+---
+
+:::caution
+版本 v3.1.0-beta.2 以上支持
+:::
+
+## 二次开发
+
+原生小程序代码:
+
+```jsx
+Page({
+ data: {
+ text: 'Hello World'
+ }
+})
+
+
+ {{ text }}
+
+```
+
+转换后:
+
+```javascript
+import { Block, View } from '@tarojs/components'
+import React from 'react'
+import Taro from '@tarojs/taro'
+import withWeapp from '@tarojs/with-weapp'
+import Title from '../../components/title/index'
+import './index.scss'
+
+@withWeapp({
+ data: {
+ text: 'Hello World'
+ }
+})
+class _C extends React.Component {
+ render() {
+ const { text } = this.data
+ return {text}
+ }
+}
+
+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 的生命周期,完整对应关系如下:
+
+|小程序生命周期|Taro 生命周期|
+| :-- | :-- |
+| onShow | componentDidShow |
+| onHide | componentDidHide |
+| App.onLaunch | onLaunch |
+| Page.onLoad | onLoad |
+| Page.onReady | onReady |
+| Page.onUnload | componentWillUnmount |
+| Component.created | componentWillMount |
+| Component.attached | componentDidMount |
+| Component.ready | Page.onReady |
+| Component.detached | componentWillUnmount |
+
diff --git a/versioned_docs/version-3.x/css-in-js.md b/versioned_docs/version-3.x/css-in-js.md
index 68755d112416..00a2edb8c26b 100644
--- a/versioned_docs/version-3.x/css-in-js.md
+++ b/versioned_docs/version-3.x/css-in-js.md
@@ -16,7 +16,7 @@ $ npm i linaria
其次配置项目根目录的 `babel.config.js`:
-```js
+```js title="babel.config.js"
module.exports = {
presets: [
['taro', {
@@ -30,7 +30,7 @@ module.exports = {
之后配置 `config/index.js`
-```js
+```js title="config/index.js"
const config = {
mini: {
webpackChain(chain, webpack) {
@@ -49,7 +49,7 @@ const config = {
最后在项目根目录新建 `linaria.config.js`
-```js
+```js title="linaria.config.js"
// linaria 配置详见 https://github.com/callstack/linaria/blob/master/docs/CONFIGURATION.md#options
module.exports = {
rules: [
diff --git a/versioned_docs/version-3.x/css-modules.md b/versioned_docs/version-3.x/css-modules.md
index 7d550484bb36..bbee1769788a 100644
--- a/versioned_docs/version-3.x/css-modules.md
+++ b/versioned_docs/version-3.x/css-modules.md
@@ -8,7 +8,7 @@ Taro 中内置了 [CSS Modules](https://github.com/css-modules/css-modules) 的
小程序端开启
-```js
+```js title="config/index.js"
weapp: {
module: {
postcss: {
@@ -27,7 +27,7 @@ weapp: {
H5 端开启
-```js
+```js title="config/index.js"
h5: {
module: {
postcss: {
@@ -93,3 +93,7 @@ export default class Test extends Component {
}
}
```
+
+## 相关阅读
+
+[开源插件 weapp-css-modules - 极致追求,让小程序代码包立减 10% 的插件](https://taro-club.jd.com/topic/2264/%E6%9E%81%E8%87%B4%E8%BF%BD%E6%B1%82-%E8%AE%A9%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%BB%A3%E7%A0%81%E5%8C%85%E7%AB%8B%E5%87%8F-10-%E7%9A%84%E6%8F%92%E4%BB%B6-weapp-css-modules)
\ No newline at end of file
diff --git a/versioned_docs/version-3.x/debug-config.md b/versioned_docs/version-3.x/debug-config.md
index 603893a8a3d5..b37e194fd3e5 100644
--- a/versioned_docs/version-3.x/debug-config.md
+++ b/versioned_docs/version-3.x/debug-config.md
@@ -43,7 +43,7 @@ yarn global add rollup
launch.json 有以下预设配置:
-```json
+```json title="launch.json"
{
// ...
"configurations": [
@@ -83,7 +83,7 @@ launch.json 有以下预设配置:
可以这样配置 launch.json:
-```json
+```json title="launch.json"
{
// ...
"configurations": [
@@ -108,7 +108,7 @@ launch.json 有以下预设配置:
可以这样配置 launch.json:
-```json
+```json title="launch.json"
{
// ...
"configurations": [
diff --git a/versioned_docs/version-3.x/envs-debug.md b/versioned_docs/version-3.x/envs-debug.md
index 6d613d3a7286..f882f09b1b7b 100644
--- a/versioned_docs/version-3.x/envs-debug.md
+++ b/versioned_docs/version-3.x/envs-debug.md
@@ -3,7 +3,8 @@ title: 多端同步调试
---
从 1.3.5 版本开始,可以在 dist 目录下创建一个与编译的目标平台名同名的目录,并将结果放在这个目录下,例如编译到微信小程序,最终结果是在 dist/weapp 目录下,这样做的好处是,各个平台使用独立的目录互不影响,从而达到多端同步调试的目的,在 `config/index.js` 配置如下:
-```
+
+```js title="/config/index.js"
outputRoot: `dist/${process.env.TARO_ENV}`
```
diff --git a/versioned_docs/version-3.x/envs.md b/versioned_docs/version-3.x/envs.md
index 2cf44bb91071..6dd8e972507c 100644
--- a/versioned_docs/version-3.x/envs.md
+++ b/versioned_docs/version-3.x/envs.md
@@ -81,7 +81,7 @@ import Test from '../../components/test'
增加 `set_title.h5.js`,代码如下
-```js
+```js title="set_title.h5.js"
export default function setTitle (title) {
document.title = title
}
@@ -89,7 +89,7 @@ export default function setTitle (title) {
增加 `set_title.weapp.js`,代码如下
-```js
+```js title="set_title.weapp.js"
import Taro from '@tarojs/taro'
export default function setTitle (title) {
Taro.setNavigationBarTitle({
@@ -145,7 +145,7 @@ Taro 3 里的多端文件由 [MultiPlatformPlugin](https://github.com/NervJS/tar
假如我们有一个 npm 包名叫 @taro-mobile,需要解析里面的多端文件,可以在 taro 的配置文件中这样修改 MultiPlatformPlugin 的配置:
-```js
+```js title="/config/index.js"
// mini 也可改为 h5,分别对应小程序与 h5 端配置
mini: {
webpackChain (chain) {
diff --git a/versioned_docs/version-3.x/migration.md b/versioned_docs/version-3.x/migration.md
index 820d311f587c..a5dda4281854 100644
--- a/versioned_docs/version-3.x/migration.md
+++ b/versioned_docs/version-3.x/migration.md
@@ -325,7 +325,3 @@ import { useState, useEffect } from 'react' // 框架 Hooks (基础 Hooks)
## $scope 和 $componentType
由于 Taro Next 没有自定义组件,所以也没有了 `this.$scope` 和 `this.$componentType` 的概念。`getCurrentInstance().page` 可以返回当前小程序页面的实例。
-
-## 相关阅读
-
-[Taro 版本升级权威指南](/blog/2020-09-01-taro-versions)
\ No newline at end of file
diff --git a/versioned_docs/version-3.x/mini-third-party.md b/versioned_docs/version-3.x/mini-third-party.md
index 249dcdb29b46..bff39f906793 100644
--- a/versioned_docs/version-3.x/mini-third-party.md
+++ b/versioned_docs/version-3.x/mini-third-party.md
@@ -2,74 +2,86 @@
title: 使用小程序原生第三方组件和插件
---
-Taro 支持使用小程序的第三方组件和插件,例如 [echarts-for-weixin](https://github.com/ecomfe/echarts-for-weixin),使用方式也异常的简单。
+Taro 支持使用小程序的第三方组件和插件,使用方式也异常的简单。
-**但是值得注意的是,如果在 Taro 项目引用了小程序原生的第三方组件和插件,那么该项目将不再具备多端转换的能力,例如,如果使用了微信小程序的第三方组件,那么项目只能转换成微信小程序,转义成其他平台会失效,使用其他小程序原生组件同理**。
+> 注意:如果在 Taro 项目引用了小程序原生的第三方组件和插件,那么该项目将**不再具备多端转换的能力**,例如,如果使用了微信小程序的第三方组件,那么项目只能转换成微信小程序,转义成其他平台会失效,使用其他小程序原生组件同理。
-## 引入第三方组件
+## 使用第三方原生组件
-首先需要将第三方组件库下载到项目的 `src` 目录下,随后在页面或者组件里通过配置 `usingComponents` 指定需要引用的第三方组件即可,组件调用的时候需要按照 JSX 的使用规范来进行传参和事件绑定。
+首先需要将第三方组件库下载到项目的 `src` 目录下,随后在页面或者组件里通过配置 `usingComponents` 指定需要引用的第三方组件即可。
-`usingComponents` 指定的第三方组件名字需要以**小写**开头。
+组件调用的时候需要**按照 JSX 的使用规范**来进行传参和事件绑定。
-```jsx
-import Taro, { Component } from '@tarojs/taro'
-import { View } from '@tarojs/components'
+### 使用方法
-function initChart () {
- // ....
-}
+1. 在页面配置文件中配置 `usingComponents` 属性。
-export default class Menu extends Component {
- static defaultProps = {
- data: []
- }
+> 注意:Taro3 中没有自定义组件,组件是没有配置文件的。usingComponents 必须配置在“页面”的配置文件中。
- constructor (props) {
- super(props)
- this.state = {
- ec: {
- onInit: initChart
- }
- }
+```js {2} title="page.config.js"
+export default {
+ usingComponents: {
+ // 定义需要引入的第三方组件
+ // 1. key 值指定第三方组件名字,以小写开头
+ // 2. value 值指定第三方组件 js 文件的相对路径
+ 'ec-canvas': '../../components/ec-canvas/ec-canvas'
}
+}
+```
+
+2. JSX 中引用
- componentWillMount () {
- console.log(this) // this -> 组件 Menu 的实例
+```jsx {14} title="page.js"
+import React, { Component } from 'react'
+import { View } from '@tarojs/components'
+
+export default class Index extends Component {
+ this.state = {
+ ec: {
+ onInit: function () {}
+ }
}
render () {
return (
-
+
)
}
}
+```
-// menu.config.js
+### 事件
-export default {
- // 定义需要引入的第三方组件
- usingComponents: {
- 'ec-canvas': '../../components/ec-canvas/ec-canvas' // 书写第三方组件的相对路径
- }
-}
+事件以 `on` 开头,取代原生绑定语法中的 `bind`。
+
+### selectComponent
+
+可以使用小程序页面实例的 `selectComponent` API 获取第三方原生组件的实例。
+
+```js
+import { getCurrentInstance } from '@tarojs/taro'
+
+const { page } = getCurrentInstance()
+page.selectComponent('#mychart-dom-area')
```
### 使用 Slot
在 React 中使用 ``(首字母小写),在 Vue 中使用 ``(由于 `slot` 在 Vue 中是内置组件)。
+### 使用 vant-weapp
+
+使用 `vant-weapp` 第三方原生组件库:[示例项目](https://github.com/NervJS/taro3-vant-sample)。
-## 引入插件
+## 使用小程序插件
### 引入插件代码包
使用插件前,使用者要在 `app.confg.js` 的配置中声明需要使用的插件,例如
-```jsx
-// app.config.js
+```jsx title="app.config.js"
export default {
plugins: {
myPlugin: {
diff --git a/versioned_docs/version-3.x/miniprogram-plugin.md b/versioned_docs/version-3.x/miniprogram-plugin.md
index d6b42783f42d..485c1164bca5 100644
--- a/versioned_docs/version-3.x/miniprogram-plugin.md
+++ b/versioned_docs/version-3.x/miniprogram-plugin.md
@@ -50,7 +50,7 @@ taro build --plugin weapp --watch
plugin.json 的 **pages** 字段加入页面插件路径:
-```json
+```json title="plugin.json"
{
"pages": {
"list": "pages/list/list"
@@ -60,7 +60,7 @@ plugin.json 的 **pages** 字段加入页面插件路径:
页面使用路径: **plugin://[app.js 中注册的插件名]/[plugin.json 中注册的页面名]** 进行跳转。
-```jsx
+```jsx {1}
Go to pages/list!
@@ -70,7 +70,7 @@ plugin.json 的 **pages** 字段加入页面插件路径:
plugin.json 的 **publicComponents** 字段加入组件插件路径:
-```json
+```json title="plugin.json"
{
"publicComponents": {
"avatar": "components/avatar/avatar"
@@ -80,7 +80,7 @@ plugin.json 的 **publicComponents** 字段加入组件插件路径:
在页面配置 config.usingComponents 中配置好插件名和插件路径(**plugin://[app.js 中注册的插件名]/[plugin.json 中注册的组件名]**):
-```jsx
+```jsx {4}
export default class Index extends Component {
config = {
usingComponents: {
@@ -114,7 +114,7 @@ const extraProps = {
plugin.json 的 **main** 字段加入接口插件路径:
-```json
+```json title="plugin.json"
{
"main": "index.js"
}
diff --git a/versioned_docs/version-3.x/nerv.md b/versioned_docs/version-3.x/nerv.md
index 0536b3c0040b..f73607c863bb 100644
--- a/versioned_docs/version-3.x/nerv.md
+++ b/versioned_docs/version-3.x/nerv.md
@@ -8,7 +8,7 @@ title: Nerv
在使用第三方 React 库时,需要在[配置文件](config-detail.md#miniwebpackchain) `webpack.resolve.alias`,把 `react` 和 `react-dom` 映射到 `nervjs`:
-```js
+```js title="/config/index.js"
{
webpackChain (chain, webpack) {
chain.merge({
diff --git a/versioned_docs/version-3.x/platform-plugin-base.md b/versioned_docs/version-3.x/platform-plugin-base.md
index 906b319fc034..a797b2e499ca 100644
--- a/versioned_docs/version-3.x/platform-plugin-base.md
+++ b/versioned_docs/version-3.x/platform-plugin-base.md
@@ -6,8 +6,7 @@ title: TaroPlatformBase
例如我们创建一个微信小程序平台:
-```js
-// program.ts
+```js title="program.ts"
import { TaroPlatformBase } from '@tarojs/service'
export default class Weapp extends TaroPlatformBase {
// ...
@@ -184,8 +183,7 @@ runner(options)
### 1. 继承基类
-```js
-// program.ts
+```js title="program.ts"
import { TaroPlatformBase } from '@tarojs/service'
class Weapp extends TaroPlatformBase {
@@ -234,8 +232,7 @@ class Weapp extends TaroPlatformBase {
规范:
-```js
-//components.ts
+```js title="components.ts"
import { singleQuote } from '@tarojs/shared'
export const components = {
@@ -319,8 +316,7 @@ internalComponent = {
除了借助 `template.mergeComponents` 进行合并,我们也可以直接修改 `template.internalComponents`。
-```js
-// program.ts
+```js title="program.ts"
class Weapp extends TaroPlatformBase {
modifyComponents () {
// 删除 Slider 组件里的一些属性
@@ -376,8 +372,7 @@ class Weapp extends TaroPlatformBase {
我们创建的平台类需要编写一个对外的接口,在其中对编译流程进行设计,最终目标是调用 `@tarojs/mini-runner` 驱动 **Webpack** 开启编译。
-```js
-// program.ts
+```js title="program.ts"
class Weapp extends TaroPlatformBase {
// ...
async start () {
diff --git a/versioned_docs/version-3.x/platform-plugin-how.md b/versioned_docs/version-3.x/platform-plugin-how.md
index 988a719cdc65..12f0ed19ac63 100644
--- a/versioned_docs/version-3.x/platform-plugin-how.md
+++ b/versioned_docs/version-3.x/platform-plugin-how.md
@@ -41,8 +41,7 @@ title: 编写端平台插件
首先我们需要编写一个 Taro 插件来注册我们的编译平台,如:
-```js
-// index.ts
+```js title="index.ts"
export default (ctx) => {
ctx.registerPlatform({
name: 'weapp',
@@ -99,8 +98,7 @@ Taro 小程序相关配置默认放在 `mini` 字段下,因此一般情况配
然后在插件入口函数中调用上述自定义平台类的编译接口:
-```js
-// index.ts
+```js title="index.ts"
import Weapp from './program'
export default (ctx) => {
@@ -221,8 +219,7 @@ export function initNativeApi (taro) {
当前扩展的小程序平台如果需要额外新增 API,建议使用一个 `apis-list.ts` 文件维护:
-```js
-// apis-list.ts
+```js title="apis-list.ts"
// 微信小程序部分扩展 API
export const _onAndSyncApis = new Set([
'getAccountInfoSync'
@@ -279,8 +276,7 @@ function processApis (taro) {
注意,Taro 相关的包需要配置 `external`,以免重复打包:
-```js
-// rollup.config.js
+```js title="rollup.config.js"
{
external: ['@tarojs/shared', '@tarojs/service']
}
@@ -292,8 +288,7 @@ Taro 核心库维护的类型可能没有包括当前插件新增的组件和 AP
创建一个类型定义文件:
-```ts
-// types/shims-iot.d.ts
+```ts title="types/shims-iot.d.ts"
// 为支付宝 IOT 小程序拓展新增的 API 和组件定义
import { ComponentType } from 'react'
import Taro from '@tarojs/taro'
@@ -319,7 +314,6 @@ declare module '@tarojs/components' {
开发者在类型定义文件中引入此文件即可:
-```ts
-// global.d.ts
+```ts title="global.d.ts"
///
```
diff --git a/versioned_docs/version-3.x/plugin.md b/versioned_docs/version-3.x/plugin.md
index 04788fe373e2..ea8bd409a9e2 100644
--- a/versioned_docs/version-3.x/plugin.md
+++ b/versioned_docs/version-3.x/plugin.md
@@ -20,7 +20,7 @@ Taro 提供了一些官方插件
`plugins` 字段取值为一个数组,配置方式如下:
-```js
+```js title="/config/index.js"
const config = {
plugins: [
// 引入 npm 安装的插件
@@ -46,7 +46,7 @@ const config = {
配置[编译配置](./config-detail.md)中的 `presets` 字段,如下。
-```js
+```js title="/config/index.js"
const config = {
presets: [
// 引入 npm 安装的插件集
diff --git a/versioned_docs/version-3.x/prerender.md b/versioned_docs/version-3.x/prerender.md
index 4521678b86d2..ed62c1854835 100644
--- a/versioned_docs/version-3.x/prerender.md
+++ b/versioned_docs/version-3.x/prerender.md
@@ -18,8 +18,7 @@ Taro Next 在一个页面加载时需要经历以下步骤:
使用 Prerender 非常简单,你可以找到项目根目录下的 `config` 文件夹,根据你的项目情况更改 `index.js`/`dev.js`/`prod.js` 三者中的任意一个[项目配置](./config.md),在编译时 Taro CLI 会根据你的配置自动启动 prerender:
-```js
-// /project/config/prod.js
+```js title="/config/index.js 或 /config/dev.js 或 /config/prod.js "
const config = {
...
mini: {
diff --git a/versioned_docs/version-3.x/react.md b/versioned_docs/version-3.x/react.md
index f2e1cf468029..5439f718f004 100644
--- a/versioned_docs/version-3.x/react.md
+++ b/versioned_docs/version-3.x/react.md
@@ -8,7 +8,7 @@ title: React
每一个 Taro 应用都需要一个入口组件用来注册应用,入口文件默认是 `src` 目录下的 `app.js`,在 Taro 中使用 React,入口组件必须导出一个 React 组件,在入口组件中我们可以设置全局状态或访问小程序入口实例的生命周期:
-```jsx
+```jsx title="app.js"
import React, { Component } from 'react'
// 假设我们要使用 Redux
import { Provider } from 'react-redux'
@@ -46,8 +46,7 @@ export default App
对于一个入口文件(例如`app.jsx`)而言,我们可以新增一个 `app.config.js` 的文件进行全局配置,`app.config.js` 的默认导出就是全局配置,配置规范基于微信小程序的[全局配置](https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE)进行制定,所有平台进行统一:
-```js
-// app.config.js
+```js title="app.config.js"
export default {
pages: [
'pages/index/index'
@@ -125,9 +124,9 @@ export default {
程序发生脚本错误或 API 调用报错时触发,微信小程序中也可以使用 `Taro.onError` 绑定监听
-#### componentDidNotFound(Object)
+#### onPageNotFound(Object)
-> 在微信/字节跳动小程序中这一生命周期方法对应 `onPageNotFound`,其他端尚未实现
+> 在微信/字节跳动小程序中这一生命周期方法对应 `onPageNotFound`,H5 端也支持,其他端尚未实现
> 微信小程序中,基础库 1.9.90 开始支持
程序要打开的页面不存在时触发,微信小程序中也可以使用 `Taro.onPageNotFound` 绑定监听
@@ -190,8 +189,7 @@ export default Index
### 配置文件
和入口组件一样,对于一个页面文件(例如`./pages/index/index.jsx`)而言,我们可以新增一个 `./pages/index/index.config.js` 的文件进行页面配置,`index.config.js` 的默认导出就是[页面配置](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html):
-```js
-// ./pages/index/index.jsx
+```js title="./pages/index/index.jsx"
export default {
navigationBarTitleText: '首页'
}
@@ -325,8 +323,7 @@ Object 参数说明:
示例代码
-```jsx
-// page.js
+```jsx title="page.js"
export default class Index extends Component {
onShareAppMessage (res) {
if (res.from === 'button') {
@@ -417,8 +414,7 @@ onAddToFavorites(res) {
| query | 自定义页面路径中携带的参数 | 当前页面路径携带的参数 |
| imageUrl | 自定义图片路径,可以是本地文件或者网络图片。支持 PNG 及 JPG,显示图片长宽比是 1:1。 | 默认使用小程序 Logo |
-```jsx
-// page.js
+```jsx title="page.js"
class Index extends Component {
onShareTimeline () {
console.log('onShareTimeline')
@@ -523,6 +519,6 @@ function Comp () {
## 常见问题
-* `useEffect`、`componentDidMount` 中获取不到渲染层元素信息,[#7116](https://github.com/NervJS/taro/issues/7116)
+* `useEffect`、`componentDidMount` 中获取不到渲染层元素信息,[7116](https://github.com/NervJS/taro/issues/7116)
* `useEffect` 或 `useLayoutEffect` 中获取不到组件最新的宽高,[#7491](https://github.com/NervJS/taro/issues/7491)
* 嵌套层级较深时,使用 `selectorQuery` 无法查询到子元素,[#7411](https://github.com/NervJS/taro/issues/7411)
diff --git a/versioned_docs/version-3.x/redux.md b/versioned_docs/version-3.x/redux.md
index 5ded4e3d36a9..d1bf2f9f482e 100644
--- a/versioned_docs/version-3.x/redux.md
+++ b/versioned_docs/version-3.x/redux.md
@@ -14,8 +14,7 @@ $ npm install --save redux react-redux redux-thunk redux-logger
随后可以在项目 `src` 目录下新增一个 `store` 目录,在目录下增加 `index.js` 文件用来配置 `store`,按自己喜好设置 `redux` 的中间件,例如下面例子中使用 `redux-thunk` 和 `redux-logger` 这两个中间件
-```jsx
-// src/store/index.js
+```jsx title="src/store/index.js"
import { createStore, applyMiddleware, compose } from 'redux'
import thunkMiddleware from 'redux-thunk'
import rootReducer from '../reducers'
@@ -48,8 +47,7 @@ export default function configStore () {
接下来在项目入口文件 `app.js` 中使用 `redux` 中提供的 `Provider` 组件将前面写好的 `store` 接入应用中
-```jsx
-// src/app.js
+```jsx title="src/app.js"
import React, { Component } from 'react'
import { Provider } from 'react-redux'
@@ -93,16 +91,14 @@ export default App
新增 `action type`
-```jsx
-// src/constants/counter.js
+```jsx title="src/constants/counter.js"
export const ADD = 'ADD'
export const MINUS = 'MINUS'
```
新增 `reducer` 处理
-```jsx
-// src/reducers/counter.js
+```jsx title="src/reducers/counter.js"
import { ADD, MINUS } from '../constants/counter'
const INITIAL_STATE = {
@@ -127,8 +123,7 @@ export default function counter (state = INITIAL_STATE, action) {
}
```
-```jsx
-// src/reducers/index.js
+```jsx title="src/reducers/index.js"
import { combineReducers } from 'redux'
import counter from './counter'
@@ -140,8 +135,7 @@ export default combineReducers({
新增 `action` 处理
-```jsx
-// src/actions/counter.js
+```jsx title="src/actions/counter.js"
import {
ADD,
MINUS
@@ -171,8 +165,7 @@ export function asyncAdd () {
最后,我们可以在页面(或者组件)中进行使用,我们将通过 `redux` 提供的 `connect` 方法将 `redux` 与我们的页面进行连接
-```jsx
-// src/pages/index/index.js
+```jsx title="src/pages/index/index.js"
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { View, Button, Text } from '@tarojs/components'
diff --git a/versioned_docs/version-3.x/size.md b/versioned_docs/version-3.x/size.md
index 91e167157728..a95afcfe6b00 100644
--- a/versioned_docs/version-3.x/size.md
+++ b/versioned_docs/version-3.x/size.md
@@ -8,7 +8,7 @@ title: 设计稿及尺寸单位
结合过往的开发经验,Taro 默认以 `750px` 作为换算尺寸标准,如果设计稿不是以 `750px` 为标准,则需要在项目配置 `config/index.js` 中进行设置,例如设计稿尺寸是 `640px`,则需要修改项目配置 `config/index.js` 中的 `designWidth` 配置为 `640`:
-```jsx
+```jsx title="/config/index.js"
const config = {
projectName: 'myProject',
date: '2018-4-18',
@@ -30,7 +30,7 @@ const DEVICE_RATIO = {
建议使用 Taro 时,设计稿以 iPhone 6 `750px` 作为设计尺寸标准。
如果你的设计稿是 `375` ,不在以上三种之中,那么你需要把 `designWidth` 配置为 `375`,同时在 `DEVICE_RATIO` 中添加换算规则如下:
-```jsx
+```jsx {5}
const DEVICE_RATIO = {
'640': 2.34 / 2,
'750': 1,
@@ -108,7 +108,7 @@ REM 单位允许的小数位。
配置规则对应到 `config/index.js` ,例如:
-```js
+```js {9-14,20-25} title="/config/index.js"
{
h5: {
publicPath: '/',
@@ -139,9 +139,9 @@ REM 单位允许的小数位。
}
```
-## 忽略
+## CSS 编译时忽略(过滤)
-### 属性
+### 忽略单个属性
当前忽略单个属性的最简单的方法,就是 px 单位使用大写字母。
@@ -158,6 +158,58 @@ REM 单位允许的小数位。
}
```
-### 文件
+### 忽略样式文件
+
+对于头部包含注释 `/*postcss-pxtransform disable*/` 的文件,插件不予处理。
+
+### 忽略样式举例
+
+样式文件里多行文本省略时我们一般如下面的代码:
+
+```css {3}
+.textHide {
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp:2;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+```
+
+但 Taro 编译后少了 `-webkit-box-orient: vertical;` 这条样式属性,此时我们需要忽略掉这条样式
+
+#### 忽略样式方法 1 加入 CSS 注释强制声明忽略下一行
+
+```css {1}
+/* autoprefixer: ignore next */
+-webkit-box-orient: vertical;
+```
+
+#### 忽略样式方法 2 加入 CSS 注释强制声明注释中间多行
+
+```css {1,3}
+/* autoprefixer: off */
+-webkit-box-orient: vertical;
+/* autoprefixer: on */
+```
+
+#### 忽略样式方法 3 写成行内样式
+
+```HTML {2-9}
+
+ 这是要省略的内容这是要省略的内容这是要省略的内容
+
+```
+
+### 相关链接
-对于头部包含注释 `/*postcss-pxtransform disable*/` 的文件,插件不予处理。
\ No newline at end of file
+- [Taro多行文本省略不生效](https://taro-club.jd.com/topic/2270/taro%E5%A4%9A%E8%A1%8C%E6%96%87%E6%9C%AC%E7%9C%81%E7%95%A5%E4%B8%8D%E7%94%9F%E6%95%88)
\ No newline at end of file
diff --git a/versioned_docs/version-3.x/static-reference.md b/versioned_docs/version-3.x/static-reference.md
index 0884d311cabc..aa9533ec9246 100644
--- a/versioned_docs/version-3.x/static-reference.md
+++ b/versioned_docs/version-3.x/static-reference.md
@@ -70,7 +70,7 @@ Taro 默认会对 `1kb` 大小以下的资源进行转换,如果需要修改
具体配置如下
-```javascript
+```js title="/config/index.js"
// 小程序端样式引用本地资源内联
url: {
enable: true,
diff --git a/versioned_docs/version-3.x/taroize-troubleshooting.md b/versioned_docs/version-3.x/taroize-troubleshooting.md
new file mode 100644
index 000000000000..6aa3be0c6c3c
--- /dev/null
+++ b/versioned_docs/version-3.x/taroize-troubleshooting.md
@@ -0,0 +1,291 @@
+---
+title: Troubleshooting
+---
+
+## 不支持的小程序特性
+
+### 入口 App 对象
+
+|属性|说明|
+|:--|:--|
+|onError||
+|onPageNotFound||
+|onUnhandledRejection||
+|onThemeChange||
+
+### 页面 Page 对象
+
+|属性|说明|
+|:--|:--|
+|selectComponent|建议使用 React ref 重构|
+|selectAllComponents|建议使用 React ref 重构|
+|selectOwnerComponent|建议使用 React ref 重构|
+|groupSetData||
+
+### 自定义组件
+
+|属性|说明|
+|:--|:--|
+|moved||
+|externalClasses|Taro 3 不存在自定义组件,建议规范类名或使用 CSS Module 代替|
+|relations||
+|options||
+|definitionFilter||
+
+### wxml 语法
+
+|属性|说明|
+|:--|:--|
+|循环|[部分语法有限制]|
+|事件|[部分语法有限制](./taroize-troubleshooting#2-事件)|
+|引用|[部分语法有限制](./taroize-troubleshooting#16-include-里不支持使用-template)|
+|wxs|[部分语法有限制](./taroize-troubleshooting#15-不支持-wxs-里的-getregexp-方法)|
+
+## 关键问题
+
+### 1. 没有处理基类
+
+原生开发中,常常会把 App、Page、Component 构造对象的公共逻辑整合到基类中。
+
+如 **Vant-weapp** 中:
+
+```js
+// 组件
+VantComponent({
+ data: {}
+})
+// 基类
+function VantComponent(vantOptions = {}) {
+ // 整合组件独有配置 vantOptions 和公共配置到最终的配置对象 options 中
+ // ...
+
+ // 调用小程序的 Component 方法构造自定义组件
+ Component(options);
+}
+```
+
+Taro 在编译时只能识别出入口、页面、组件文件中存在的 `App()`、`Page()`、`Component()` 调用,使用基类对配置封装后就不存在这些调用。因此编译后的 `withWeapp` 获得的参数是 `{}`。
+
+```js
+VantComponent({
+ data: {}
+})
+// withWeapp 中应该传入小程序配置对象
+@withWeapp({})
+class _C extends React.Component {}
+```
+
+因此我们需要手动修改:
+
+```js
+// 基类
+function VantComponent(vantOptions = {}) {
+ // 整合组件独有配置 vantOptions 和公共配置到最终的配置对象 options 中
+ // ...
+
+ // 调用小程序的 Component 方法构造自定义组件
+ // Component(options);
+
+ // 1. 基类直接返回整合后的 options
+ return options
+}
+```
+
+
+```js
+// 2. 把基类创建的配置传入 withWeapp:
+const options = VantComponent({
+ data: {}
+})
+@withWeapp(options)
+class _C extends React.Component {}
+```
+
+### 2. 样式作用域
+
+微信小程序中的自定义组件,转换后会生成一个 Taro 中的 React/Vue 组件。
+
+但是 Taro 中使用 React/Vue 开发的组件,编译到小程序平台时,并不会生成对应的小程序自定义组件。
+
+**因此微信小程序自定义组件的样式隔离特性,在转换为 Taro 后就会丢失。**
+
+#### 解决办法:
+
+1. 修改冲突的选择器。
+2. 使用 CSS Modules 进行改写。
+
+## 常见问题
+
+### 1. wxml 语法转换问题
+
+把 `wxml` 转换为 `JSX` 是通过操作 `AST` 实现的,有一些写法可能没有考虑到,或难以适配,从而导致报错。
+
+以下是一些已知问题,需要手动修复:
+
+#### 1.1 组件同时使用 `wx:for` 和 `wx:if` 语句时转换错误
+
+当组件上同时使用了 `wx:for` 和 `wx:if` 语句,并且使用了当前**循环元素 item** 或**循环下标 index** 做判断条件时,转换后会报错。
+
+例如:
+
+```jsx
+// 转换前(注意判断条件使用了循环下标 index):
+
+ objectArray item: {{item.id}}
+
+```
+
+```jsx
+// 转换后:
+{index % 2 !== 0 && (
+
+ {objectArray.map((item, index) => {
+ return (
+
+ {'objectArray item: ' + item.id}
+
+ )
+ })}
+
+)}
+```
+
+上例可见,对于条件语句的转换,目前的处理会把条件提取到组件外部。但是如果条件使用了 `item` 或 `index` 时,这样的提取逻辑会导致**变量未定义**的报错。
+
+暂时可以通过手动修复解决:
+
+方法一,修改**编译前**的代码,把循环和条件语句拆开到两个组件中:
+
+```jsx
+
+
+ objectArray item: {{item.id}}
+
+
+```
+
+方法二,修改**编译后**的代码,把条件判断放进循环体中:
+
+```jsx
+
+ {objectArray.map((item, index) => {
+ return (
+
+ {index % 2 !== 0 && {'objectArray item: ' + item.id}}
+
+ )
+ })}
+
+```
+
+#### 1.2 根元素不能含有 `hidden` 属性。
+
+#### 1.3 编译时报错:SyntaxError: Unexpected token
+
+尖括号 “<” 右侧需要留一个空格,[#4243](https://github.com/NervJS/taro/issues/4243)
+
+##### 解决办法:
+
+检查是否存在以下写法:
+
+```jsx
+{{a <4? "1": "2"}}
+```
+
+改为:
+
+```jsx
+{{a < 4? "1": "2"}}
+```
+
+#### 1.4 运行时报错:ReferenceError: item is not defined
+
+查看编译后的 JSX,是否因为漏了从 `this.data` 中取出变量,如:
+
+```
+// 下面的代码没有引用 item
+const { a, b, c } = this.data
+```
+
+##### 解决办法:
+
+`this.data` 中的变量名,不要和用于指定数组当前下标的变量名,默认值为 `item`,或由 `wx:for-index` 具体指定的变量名相同。
+
+
+#### 1.5 不支持 WXS 里的 GetRegExp 方法
+
+使用 `RegExp` 构造正则表达式。
+
+#### 1.6 `` 里不支持使用 ``
+
+#### 1.7 template 里暂不支持使用 catch 事件
+
+### 2. 事件
+
+* 事件不支持绑定字符串。
+* `catchtouchmove` 转换后只能停止回调函数的冒泡,不能阻止滚动穿透。如要阻止滚动穿透,可以手动给编译后的 `View` 组件加上 `catchMove` 属性。
+* 不支持事件捕获阶段。
+* 不支持使用 WXS 函数响应事件。
+* 不支持互斥事件绑定 `mut-bind`。
+* 不支持 `mark` 来识别具体触发事件的 target 节点。
+
+### 3. CommonJS 和 ES 模块化语法不能混用
+
+可能遇到的报错信息:
+
+* Cannot assign to read only property 'exports' of object
+* export '[something]' (imported as '[name]') was not found in '[somePath]'
+
+在使用到小程序 API 的地方,Taro 会把 `wx.api()` 转换为 `Taro.api()`,同时在文件的头部加上 `import Taro from '@tarjs/taro`。
+
+如果此文件原本是使用 **CommonJS** 组织模块,可能会出现问题,需要手动修复。
+
+### 4. selectorQuery API 获取不到 DOM
+
+1. 一定要在 `onReady`、`ready` 生命周期中才能调用小程序 API 获取 DOM。
+2. 不需要调用 `.in(this)` 方法。
+
+### 5. Image 没有处理动态拼接的 src
+
+Taro 会对 `Image` 组件的 src 进行处理:
+
+```jsx
+// 转换前:
+
+// 转换后:
+
+```
+
+但如果 `src` 是动态拼接的字符串,则需要手动修改:
+
+```jsx
+// 转换前:
+
+// 转换后:
+
+// 手动修改,图片也需要手动拷贝到 taroConert/src 对应目录下:
+
+```
+
+### 6. require 的参数不能是变量
+
+可能遇到的报错信息:
+
+* The "path" argument must be of type string. Received type undefined
+
+不支持转换以下写法,[#4749](https://github.com/NervJS/taro/issues/4749):
+
+```js
+var pathTest = './test.js'
+var test = require(pathTest)
+```
+
+Taro 目前只能转换 `require` 字符串的写法。
+
+### 7. 没有处理 export from 语法
+
+暂时手动处理,[#5131](https://github.com/NervJS/taro/issues/5131)。
+
+### 8. Issues
+
+反向转换的更多问题,请查阅 Taroize 相关 [Issues](https://github.com/NervJS/taro/issues?q=is%3Aopen+is%3Aissue+label%3AA-taroize)。
diff --git a/versioned_docs/version-3.x/taroize.md b/versioned_docs/version-3.x/taroize.md
index 1653ac7433d8..59f0af756af1 100644
--- a/versioned_docs/version-3.x/taroize.md
+++ b/versioned_docs/version-3.x/taroize.md
@@ -2,250 +2,34 @@
title: 微信小程序转 Taro
---
-> 自 `v1.2.0` 开始支持此功能
+Taro 可以把**原生微信小程序应用转换为 Taro 项目**,从而使项目成为多端应用。
-Taro 可以将你的原生微信小程序应用转换为 Taro 代码,进而你可以通过 `taro build` 的命令将 Taro 代码转换为对应平台的代码,或者对转换后的 Taro 代码进行用 React 的方式进行二次开发。
+转换后的代码可读性高,能够继续使用 **React**(将来支持转换为 **Vue**)进行二次开发。
-微信原生小程序转 Taro 的操作非常简单,首先必须安装使用 `npm i -g @tarojs/cli` 安装 Taro 命令行工具,其次在命令行中定位到小程序项目的根目录,根目录中运行:
+### 反向转换步骤
+
+1. 安装 Taro 命令行工具:
```bash
-$ taro convert
+$ npm i -g @tarojs/cli
```
-即可完成转换。转换后的代码保存在根目录下的 `taroConvert` 文件夹下。你需要定位到 `taroConvert` 目录执行 `npm install` 命令之后就可以使用 `taro build` 命令编译到对应平台的代码。
-
-## 二次开发
-
-假设已有一个转换后文件如下:
-
-```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: '物流详情'
- }
+2. 在微信小程序项目的根目录中运行 `convert` 命令进行转换:
- render() {
- const {
- orderDetail: orderDetail,
- logisticsTraces: logisticsTraces
- } = this.state
- return (
-
-
-
- 物流单号
- {orderDetail.logistics.trackingNumber}
-
-
- 物流公司
- {orderDetail.logistics.shipperName}
-
-
-
-
-
- {logisticsTraces.map((item, index) => {
- return (
-
-
-
-
-
-
-
-
- {item.AcceptTime}
- {item.AcceptStation}
-
-
- )
- })}
-
-
-
- )
- }
-}
-
-export default _C
+```bash
+# 转换后的代码保存在根目录下的 `taroConvert` 文件夹下
+$ taro convert
```
-它看起来就像普通的 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 | componentDidCatchError |
-| App.onLaunch | componentWillMount |
-| Component.created | componentWillMount |
-| attached | componentDidMount |
-| ready | componentDidMount |
-| detached | componentWillUnmount |
-| moved | 保留 |
+3. 进入 `taroConvert` 目录,安装依赖:
-## 常见问题
-
-### 在小程序 IDE 显示 `_createData` 错误
-
-这个错误通常是由于原始代码的初始 `data` 中没有对应的数据,后来通过 `this.setData` 补充数据造成的。在 Taro 中推荐不管是 `state(data)` 还是 `properties(props)` 都要设置一个默认值。你可以在类构造器或修改原始代码提供一个默认值解决这个问题,这也应该是编写代码的最佳实践。
-
-### 转换 `wxParse` 报错不存在文件
-
-这是由于 `wxParse` 的源码使用了一个[不存在的 `template`](https://github.com/icindy/wxParse/issues/255) 声明造成的。你可以修改 `wxParse` 的源码文件 `wxParse.wxml` 134 行到 207 行:
-
-```html
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+```bash
+$ cd taroConvert
+$ npm install
```
-把 `` 的模板内所有 `` 修改为 `` 再运行 `taro convert` 即可。这样修改之后还会取消原来 `wxParse` 只能处理 11 级 HTML 嵌套的问题,理论上内存不爆栈可以处理无限级 HTML 嵌套。
-
-### 不支持 `relations` 和 `Behavior`
+4. 运行 `build` 命令,把项目编译到任意平台:
-目前转换暂只支持转换 `Page`、`Component` 、`App` 三种构造器创造的小程序组件实例。 `relations` 和 `Behavior` 在其他许多小程序端中还没有对应的实现,我们认为实现这两个功能意义不大。
-
-### 转换 wepy 文件不成功
-
-目前只能支持转换使用原生微信小程序开发的应用。
+```bash
+$ taro build --type [platform]
+```
diff --git a/versioned_docs/version-3.x/template.md b/versioned_docs/version-3.x/template.md
index 7f904c642cf8..5880ceff125b 100644
--- a/versioned_docs/version-3.x/template.md
+++ b/versioned_docs/version-3.x/template.md
@@ -87,7 +87,7 @@ zip 包解压出单文件夹,文件夹内包含若干模板。
开发者可以在模板根目录加入 **template_creator.js** 文件,文件对外 exports 包含 handler 与 basePageFiles 字段的对象:
-```js
+```js {5,16} title="template_creator.js"
function createWhenTs (params) {
return params.typescript ? true : false
}
@@ -134,8 +134,7 @@ module.exports = {
##### 例子
-```ejs
-// index.js
+```ejs title="index.js"
<%if (typescript) {-%>
import Taro, { Component, Config } from '@tarojs/taro'
<%} else { -%>
@@ -197,8 +196,7 @@ return: boolean/object
当用户选择了使用 typescript 时,才生成 **global.d.ts** 和 **tsconfig.json** 文件。
-```js
-// template_creator.js
+```js title="template_creator.js"
function createWhenTs (params) {
return params.typescript ? true : false
}
@@ -221,8 +219,7 @@ basePageFiles 告诉 CLI,当用户使用 `taro create` 命令创建页面时
当用户使用命令 `taro create --page=detail` 时,会创建 **/src/pages/detail/detail.jsx** 与 **/src/pages/detail/detail.css** 两个文件。
-```js
-// template_creator.js
+```js title="template_creator.js"
const handler = {
'/src/pages/index/index.jsx' ({ pageName }) {
return { setPageName: `/src/pages/${pageName}/${pageName}.jsx` }
diff --git a/versioned_docs/version-3.x/tutorial.md b/versioned_docs/version-3.x/tutorial.md
index 542886c0aeb2..24484dce19f7 100644
--- a/versioned_docs/version-3.x/tutorial.md
+++ b/versioned_docs/version-3.x/tutorial.md
@@ -73,8 +73,7 @@ Taro 中全局配置所包含的配置项及各端支持程度如下
则需要在入口文件配置中写
-```jsx
-// app.config.js
+```jsx title="app.config.js"
export default {
pages: [
'pages/index/index',
@@ -124,8 +123,7 @@ export default {
配置示例如下:
-```jsx
-// app.config.js
+```jsx title="app.config.js"
export default {
pages: [
'pages/index/index',
diff --git a/versioned_docs/version-3.x/vue.md b/versioned_docs/version-3.x/vue.md
index 522b4442a4a2..1019ef6f14fd 100644
--- a/versioned_docs/version-3.x/vue.md
+++ b/versioned_docs/version-3.x/vue.md
@@ -9,7 +9,7 @@ title: Vue
每一个 Taro 应用都需要一个入口组件用来注册应用,入口文件默认是 `src` 目录下的 `app.js`。
在 Taro 中使用 Vue,入口组件必须导出一个 Vue 组件,在入口组件中我们可以设置全局状态或访问小程序入口实例的生命周期:
-```jsx
+```jsx title="src/app.js"
import Vue from 'vue'
// 假设我们已经在 './store' 配置好了 vuex
import store from './store'
@@ -29,8 +29,7 @@ export default App
对于一个入口文件(例如`app.js`)而言,我们可以新增一个 `app.config.js` 的文件进行全局配置,`app.config.js` 的默认导出就是小程序的[全局配置](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html):
-```js
-// app.config.js
+```js title="app.config.js"
export default {
pages: [
'pages/index/index'
@@ -439,8 +438,7 @@ onAddToFavorites(res) {
以上成员方法在 Taro 的页面中同样可以使用,书写同名方法即可,不过需要注意的,目前暂时只有小程序端支持(支持程度如上)这些方法,编译到 H5/RN 端后这些方法均会失效。
-```js
-// ./pages/index/index.jsx
+```js title="./pages/index/index.jsx"
export default {
navigationBarTitleText: '首页'
}
diff --git a/versioned_docs/version-3.x/vue3.md b/versioned_docs/version-3.x/vue3.md
index 9a029b48ddad..9ba5513e421e 100644
--- a/versioned_docs/version-3.x/vue3.md
+++ b/versioned_docs/version-3.x/vue3.md
@@ -14,8 +14,7 @@ Taro 是如何兼容 Vue3 的,可参阅 [Taro RFC](https://github.com/NervJS/t
由于 Vue3 Global API 有变化([0009-global-api-change](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0009-global-api-change.md)),Vue3 的入口组件写法将会变成:
-```js
-// app.js
+```js title="src/app.js"
import { createApp } from 'vue'
const app = createApp({
@@ -63,3 +62,8 @@ export default {
* 小程序端非类似 HTML 表单标签规范的表单组件,如 Picker,暂不兼容 v-model。Vue3 的 v-model 绑定属性改为了 modelValue,事件绑定改为了 update:modelValue。对于 HTML 表单标签会自动对接表单的值与事件,例如 input 会自动对应 modelValue 与 value、update:modelValue 与 @input。但对于 Picker 这种小程序特有表单则无法对应,建议这种情况不使用 v-model。
* VirtualList 组件需要实现一份 Vue3 版本(待实现)
* 所有组件的 `id` 必须在整个应用中保持唯一(即使他们在不同的页面),否则可能导致事件不触发的问题,[#7317](https://github.com/NervJS/taro/issues/7317)
+
+
+## 相关阅读
+
+[使用 Vue3 开发小程序](https://taro-club.jd.com/topic/2267/%E4%BD%BF%E7%94%A8-vue3-%E5%BC%80%E5%8F%91%E5%B0%8F%E7%A8%8B%E5%BA%8F) by lillian
\ No newline at end of file
diff --git a/versioned_sidebars/version-3.x-sidebars.json b/versioned_sidebars/version-3.x-sidebars.json
index 37ce5fc4ce1c..392d5a0241cb 100644
--- a/versioned_sidebars/version-3.x-sidebars.json
+++ b/versioned_sidebars/version-3.x-sidebars.json
@@ -157,6 +157,25 @@
"type": "doc",
"id": "version-3.x/hybrid"
},
+ {
+ "collapsed": true,
+ "label": "反向转换",
+ "type": "category",
+ "items": [
+ {
+ "type": "doc",
+ "id": "version-3.x/taroize"
+ },
+ {
+ "type": "doc",
+ "id": "version-3.x/convert-to-react"
+ },
+ {
+ "type": "doc",
+ "id": "version-3.x/taroize-troubleshooting"
+ }
+ ]
+ },
{
"collapsed": true,
"label": "扩展编译平台",