微信小程序轉(zhuǎn) Taro

2020-05-12 17:45 更新

Taro 可以將你的原生微信小程序應用轉(zhuǎn)換為 Taro 代碼,進而你可以通過 taro build 的命令將 Taro 代碼轉(zhuǎn)換為對應平臺的代碼,或者對轉(zhuǎn)換后的 Taro 代碼用 React 的方式進行二次開發(fā)。

微信原生小程序轉(zhuǎn) Taro 的操作非常簡單,首先必須安裝使用 npm i -g @tarojs/cli 安裝 Taro 命令行工具,其次在命令行中定位到小程序項目的根目錄,根目錄中運行:

$ taro convert

即可完成轉(zhuǎn)換。轉(zhuǎn)換后的代碼保存在根目錄下的 taroConvert 文件夾下。你需要定位到 taroConvert 目錄執(zhí)行 npm install 命令之后就可以使用 taro build 命令編譯到對應平臺的代碼。

二次開發(fā)

假設已有一個轉(zhuǎn)換后文件如下:

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 組件,最重要的區(qū)別就在于 @withWeapp() 這個裝飾器,你可以將它理解為轉(zhuǎn)換代碼的運行時,@withWeapp() 會增加一些原來 Taro 沒有方法和屬性,例如:

this.setData

轉(zhuǎn)換后的 this.setData 的 API 相當于小程序的 this.setData 的 polyfill,他和 this.setState 最大的區(qū)別就在于,this.setData 之后 data 的數(shù)據(jù)是同步更新,而渲染是異步更新,而 setState 兩者都是異步的。

this.data 和 this.properties

this.data 和 this.properties 相當于 Taro 的 this.state 和 this.props 的 alias,當它們的數(shù)據(jù)更新時,對應的 state 和 props 也會同步更新。

生命周期

Taro 會將原始文件的生命周期鉤子函數(shù)轉(zhuǎn)換為 Taro 的生命周期,完整對應關(guān)系如下:

Page.onLoadcomponentWillMount
onShowcomponentDidShow
onHidecomponentDidHide
onReadycomponentDidMount
onUnloadcomponentWillUnmount
onErrorcomponentDidCatchError
App.onLaunchcomponentWillMount
Component.createdcomponentWillMount
attachedcomponentDidMount
readycomponentDidMount
detachedcomponentWillUnmount
moved保留

常見問題

在小程序 IDE 顯示 _createData 錯誤

這個錯誤通常是由于原始代碼的初始 data 中沒有對應的數(shù)據(jù),后來通過 this.setData 補充數(shù)據(jù)造成的。在 Taro 中推薦不管是 state(data) 還是 properties(props) 都要設置一個默認值。你可以在類構(gòu)造器或修改原始代碼提供一個默認值解決這個問題,這也應該是編寫代碼的最佳實踐。

轉(zhuǎn)換 wxParse 報錯不存在文件

這是由于 wxParse 的源碼使用了一個不存在的 template 聲明造成的。你可以修改 wxParse 的源碼文件 wxParse.wxml 134 行到 207 行:

<!--循環(huán)模版-->
<template name="wxParse1">
  <!--<template is="wxParse1" data="{{item}}" />-->
  <!--判斷是否是標簽節(jié)點-->
  <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="wxParse0" 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="wxParse0" 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="wxParse0" 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="wxParse0" 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="wxParse0" data="{{item}}" />
        </block>
      </view>
    </block>

    <!--內(nèi)聯(lián)標簽-->
    <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="wxParse0" data="{{item}}" />
      </block>
    </view>

  </block>

  <!--判斷是否是文本節(jié)點-->
  <block wx:elif="{{item.node == 'text'}}">
    <!--如果是,直接進行-->
    <template is="WxEmojiView" data="{{item}}" />
  </block>

</template>

把 <template name="wxParse1"> 的模板內(nèi)所有 <template is="wxParse2" data="{{item}}" /> 修改為 <template is="wxParse0" data="{{item}}" /> 再運行 taro convert 即可。這樣修改之后還會取消原來 wxParse 只能處理 11 級 HTML 嵌套的問題,理論上內(nèi)存不爆??梢蕴幚頍o限級 HTML 嵌套。

不支持 relations 和 Behavior

目前轉(zhuǎn)換暫只支持轉(zhuǎn)換 Page、Component 、App 三種構(gòu)造器創(chuàng)造的小程序組件實例。 relations 和 Behavior 在其他許多小程序端中還沒有對應的實現(xiàn),我們認為實現(xiàn)這兩個功能意義不大。

轉(zhuǎn)換 wepy 文件不成功

目前只能支持轉(zhuǎn)換使用原生微信小程序開發(fā)的應用。 


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號