taro 重新加载小程序_从微信小程序到Taro,不完全指南

Taro介绍

简介

Taro 是一套遵循React语法规范的多端统一开发 框架。使用Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信/百度/支付宝/字节跳动/QQ小程序、快应用、H5、React-Native 等)运行的代码。

特性

React 语法风格

Taro 遵循 React 语法规范,它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验。

快速开发微信小程序

Taro 立足于微信小程序开发,众所周知小程序的开发体验并不是非常友好,比如小程序中无法使用 npm 来进行第三方库的管理,无法使用一些比较新的 ES 规范等等,针对小程序端的开发弊端,Taro 具有以下的优秀特性支持使用 npm/yarn 安装管理第三方依赖

支持使用 ES7/ES8 甚至更新的 ES 规范,一切都可自行配置

支持使用 CSS 预编译器,例如 Sass 等

支持使用 Redux 进行状态管理

小程序 API 优化,异步 API Promise 化

支持多端开发转化

Taro 方案的初心就是为了打造一个多端开发的解决方案。目前 Taro 代码可以支持转换到 微信/百度/支付宝/字节跳动/QQ小程序 、快应用、 H5 端 以及 移动端(React Native)。

安装及使用

安装node 环境(>=8.0.0);

Taro开发工具@tarojs/cli# 使用 npm 安装 CLI

$ npm install -g @tarojs/cli

使用

使用命令创建模板项目$ taro init myApp

项目结构├── 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

各端dev环境启动$ npm run dev:h5 web

$ npm run dev:weapp 微信小程序

$ npm run dev:swan 百度小程序

$ npm run dev:alipay 支付宝小程序

$ npm run dev:tt 字节跳动小程序

$ npm run dev:qq QQ小程序

$ npm run dev:rn

生命周期

React框架中的生命周期函数被保留,新增支持小程序的几个生命周期

componentWillMount()

页面加载时触发,一个页面只会调用一次,此时页面 DOM 尚未准备好,还不能和视图层进行交互

componentDidMount()

页面初次渲染完成时触发,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互

shouldComponentUpdate(nextProps, nextState)

页面是否需要更新,返回 false 不继续更新,否则继续走更新流程

componentWillUpdate(nextProps, nextState)

页面即将更新

componentDidUpdate(prevProps, prevState)

页面更新完毕

componentWillUnmount()

页面卸载时触发,如 redirectTo 或 navigateBack 到其他页面时

componentDidShow()

页面显示/切入前台时触发

componentDidHide()

页面隐藏/切入后台时触发, 如 navigateTo 或底部 tab 切换到其他页面,小程序切入后台等

页面事件处理函数

增加在小程序中的专属事件处理函数,如下:onPullDownRefresh(): 监听用户下拉刷新事件

onReachBottom():监听用户上拉触底事件

onPageScroll(Object):监听用户滑动页面事件

onShareAppMessage(Object): 监听用户点击页面内转发按钮(Button 组件 openType='share')或右上角菜单“转发”按钮的行为,并自定义转发内容。

onTabItemTap(Object):点击 tab 时触发

设计稿及尺寸单位

在 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 中,路由功能是默认自带的,不需要开发者进行额外的路由配置。

我们只需要在入口文件的 config 配置中指定好 pages,然后就可以在代码中通过 Taro 提供的 API 来跳转到目的页面,例如:// 跳转到目的页面,打开新页面

Taro.navigateTo({

url: '/pages/page/path/name'

})

路由传参

我们可以通过在所有跳转的 url 后面添加查询字符串参数进行跳转传参,例如// 传入参数 id=2&type=test

Taro.navigateTo({

url: '/pages/page/path/name?id=2&type=test'

})

这样的话,在跳转成功的目标页的生命周期方法里就能通过 this.$router.params 获取到传入的参数,例如上述跳转,在目标页的 componentWillMount 生命周期里获取入参class C extends Taro.Component{

componentWillMount () {

console.log(this.$router.params) // 输出 { id: 2, type: 'test' }// 输出 { id: 2, type: 'test' }

}

}

state状态管理&Props

state状态更新一定是异步的,同步更新需要传入callBack

这是 Taro 和 React 另一个不同的地方:React 的 setState 不一定总是异步的,而对于 Taro 而言,setState 之后,你提供的对象会被加入一个数组,然后在执行下一个 eventloop 的时候合并它们。 例如:// 假设我们之前设置了 this.state.counter = 0

updateCounter () {

this.setState({

counter: 1

})

console.log(this.state.counter) // 这里 counter 还是 0

}

正确的做法是这样,在 setState 的第二个参数传入一个 callback:// 假设我们之前设置了 this.state.counter = 0

updateCounter () {

this.setState({

counter: 1

}, () => {

// 在这个函数内你可以拿到 setState 之后的值

})

任何组件的事件传递都要以 on 开头

但在 Taro 中,只要当 JSX 组件传入的参数(props)是函数,参数名就必须以 on 开头:const element =

const element2 =

const element3 =

环境变量 process.env 的使用

不要以解构的方式来获取通过 env 配置的 process.env 环境变量,请直接以完整书写的方式 process.env.NODE_ENV 来进行使用// 错误写法,不支持

const { NODE_ENV = 'development' } = process.env

if (NODE_ENV === 'development'){

...

}

// 正确写法

if (process.env.NODE_ENV === 'development') {

}

环境判断

Taro 在编译时提供了一些内置的环境变量来帮助用户做一些特殊处理。用于判断当前编译类型,可以通过这个变量来书写对应一些不同环境下的代码,在编译时会将不属于当前编译类型的代码去掉,只保留当前编译类型下的代码。

Taro.ENV_TYPE

ENV_TYPE.WEAPP 微信小程序环境

ENV_TYPE.SWAN 百度小程序环境

ENV_TYPE.ALIPAY 支付宝小程序环境

ENV_TYPE.TT 字节跳动小程序环境

ENV_TYPE.WEB WEB(H5)环境

ENV_TYPE.RN ReactNative 环境

关于 JSX 支持程度补充说明

由于 JSX 中的写法千变万化,我们不能支持到所有的 JSX 写法,同时由于微信小程序端的限制,也有部分 JSX 的优秀用法暂时不能得到很好地支持,特在此补充说明一下对于 JSX 的支持程度:不能使用 Array#map 之外的方法操作 JSX 数组

Taro 在小程序端实际上把 JSX 转换成了字符串模板,而一个原生 JSX 表达式实际上是一个 React/Nerv 元素(react-element)的构造器,因此在原生 JSX 中你可以随意地一组 React 元素进行操作。但在 Taro 中你只能使用 map 方法,Taro 转换成小程序中 wx:for。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:test.push()

numbers.forEach(numbers => {

if (someCase) {

a =

}

})

test.shift()

components.find(component => {

return component ===

})

components.some(component => component.constructor.__proto__ === .constructor)

以下代码不会被警告,也应当在 Taro 任意端中能够运行:numbers.filter(Boolean).map((number) => {

const element =

return

})暂不支持在 render() 之外的方法定义 JSX

由于微信小程序的 template 不能动态传值和传入函数,Taro 暂时也没办法支持在类方法中定义 JSX。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:class App extends Component{

_render() {

return

}

}

class App extends Component{

renderHeader(showHeader) {

return showHeader &&

}

}

class App extends Component{

renderHeader = (showHeader) => {

return showHeader& &

}

}

解决方案

在 render 方法中定义。class App extends Component{

render () {

const { showHeader, showMain } = this.state

const header = showHeader &&

const main = showMain &&

return (

{header}

{main}

)

}

}不能在 JSX 参数中使用对象展开符

微信小程序组件要求每一个传入组件的参数都必须预先设定好,而对象展开符则是动态传入不固定数量的参数。所以 Taro 没有办法支持该功能。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

以下代码不会被警告,也应当在 Taro 任意端中能够运行:const { id, ...rest } = obj

const [ head, ...tail] = array

const obj = { id, ...rest }

异步编程

Taro 支持使用 async functions 来让开发者获得不错的异步编程体验,开启 async functions 支持需要安装包 @tarojs/async-await$ npm install --save @tarojs/async-await

随后在项目入口文件 app.jsx 中直接 import ,就可以开始使用 async functions 功能了// src/app.jsx

import '@tarojs/async-await'

使用Redux

在 Taro 中可以自由地使用 React 生态中非常流行的数据流管理工具 Redux 来解决复杂项目的数据管理问题。而为了更方便地使用 Redux ,Taro 提供了与 react-redux API 几乎一致的包 @tarojs/redux 来让开发人员获得更加良好的开发体验。

首先请安装 redux 、 @tarojs/redux 和 @tarojs/redux-h5,以及一些需要用到的 redux 中间件$ npm install --save redux @tarojs/redux @tarojs/redux-h5 redux-thunk redux-logger

随后可以在项目 src 目录下新增一个 store 目录,在目录下增加 index.js 文件用来配置 store,按自己喜好设置 redux 的中间件,例如下面例子中使用 redux-thunk 和 redux-logger 这两个中间件// src/store/index.js

import { createStore, applyMiddleware } from 'redux'

import thunkMiddleware from 'redux-thunk'

import { createLogger } from 'redux-logger'

import rootReducer from '../reducers'

const middlewares = [

thunkMiddleware,

createLogger()

]

export default function configStore (){

const store = createStore(rootReducer, applyMiddleware(...middlewares))

return store

}

接下来在项目入口文件 app.js 中使用 @tarojs/redux 中提供的 Provider 组件将前面写好的 store 接入应用中// src/app.js

import Taro, { Component } from '@tarojs/taro'

import { Provider } from '@tarojs/redux'

import configStore from './store'

import Index from './pages/index'

import './app.scss'

const store = configStore()

class App extends Component{

config = {

pages: [

'pages/index/index'

],

window: {

navigationBarTitleText: 'Test'

}

}

render() {

return (

)

}

}

Taro.render(, document.getElementById('app'))

然后就可以开始使用了。如 redux 推荐的那样,可以增加constants 目录,用来放置所有的 action type 常量

actions 目录,用来放置所有的 actions

reducers 目录,用来放置所有的 reducers

例如我们要开发一个简单的加、减计数器功能

新增 action type// src/constants/counter.js

export const ADD = 'ADD'

export const MINUS = 'MINUS'

新增 reducer 处理// src/reducers/counter.js

import { ADD, MINUS } from '../constants/counter'

const INITIAL_STATE = {

num: 0

}

export default function counter (state = INITIAL_STATE, action) {

switch (action.type) {

case ADD:

return {

...state,

num: state.num + 1

}

case MINUS:

return {

...state,

num: state.num - 1

}

default:

return state

}

}

// src/reducers/index.js

import { combineReducers } from 'redux'

import counter from './counter'

export default combineReducers({

counter

})

新增 action 处理// src/actions/counter.js

import {

ADD,

MINUS

} from '../constants/counter'

export const add = () => {

return {

type: ADD

}

}

export const minus = () => {

return {

type: MINUS

}

}

最后,我们可以在页面(或者组件)中进行使用,我们将通过 tarojs/redux 提供的 connect 方法将 redux 与我们的页面进行连接// src/pages/index/index.js

import Taro, { Component } from '@tarojs/taro'

import { View, Text } from '@tarojs/components'

import { connect } from '@tarojs/redux'

import './index.scss'

import { add, minus } from '../../actions/counter'

@connect(({ counter }) => ({

counter

}), (dispatch) => ({

add () {

dispatch(add())

},

dec () {

dispatch(minus())

}

}))

class Index extends Component{

config = {

navigationBarTitleText: '首页'

}

render () {

return (

+

-

{this.props.counter.num}

)

}

}

export default Index

connect 方法接受两个参数 mapStateToProps 与 mapDispatchToPropsmapStateToProps,函数类型,接受最新的 state 作为参数,用于将 state 映射到组件的 props

mapDispatchToProps,函数类型,接收 dispatch() 方法并返回期望注入到展示组件的 props 中的回调方法

Taro 代码与小程序代码混写

Taro 项目 支持 Taro 的代码与小程序(微信/百度/支付宝/字节跳动)原生的页面、组件代码混合存在,只需要将原生的页面、组件代码放入 src 目录下,随后在 入口文件 app.js 中定义好 pages 配置指向对应的原生的页面即可,在原生页面的配置中,你可以通过 usingComponents 来定义需要引入的组件,这里可以指定 Taro 组件同时也可以指定小程序原生的组件。

usingComponents 指定的小程序原生组件名字需要以小写开头。

组件库说明

API 说明

你可能感兴趣的:(taro,重新加载小程序)