taro-react
Taro支持将web框架直接运行在各个平台,开发者使用的大多数是react,vue。但是在taro中使用react开发和我们熟悉的web端还是存在一些差异,以下我们将差异详细列出。
Taro支持将web框架直接运行在各个平台,开发者使用的大多数是react,vue。但是在taro中使用react开发和我们熟悉的web端还是存在一些差异,以下我们将差异详细列出。
React API
taro3中,开发者使用真实的react,而react中的api包括Component、useState、useEffect都需要从react包中获取。
// 从 'react' 包中获取 React API
import React, { Component, useState, useEffect } from 'react'
组件
taro引入了人口组件app,和页面组件page。一个taro应用必须有一个入口组件app和最少一个页面组件page。
入口组件
每个taro应用都需要一个入口组件来注册应用,入口文件默认是src目录下的app.js。在入口组件中我们可以设置全局状态或访问小程序入口实例的生命周期。
生命周期
入口组件除了支持所有的React的生命周期外,还支持以下几个钩子函数:
- onLaunch (options),在此生命周期中通过访问 options 参数或调用 getCurrentInstance().router,可以访问到程序初始化参数。
options可选参数为:
在不同的环境中,比如在百度小程序和微信小程序中,scene是不一致的。
options.referrerInfo
- componentDidShow (options),对应onShow,程序启动,或者切换至前台时会触发,在此生命周期中通过访问 options 参数或调用 getCurrentInstance().router,可以访问到程序初始化参数。
options的可选参数一致,但是在百度小程序中,多出两个参数:
- componentDidHide (),对应onHide,程序切后台时会触发。
- onPageNotFound (Object),当访问的页面不存在时会触发。参数object可选值为:
页面组件
每一个taro页面都至少包含一个页面组件,页面组件可以通过taro路由进行跳转,也可以访问小程序的生命周期。
生命周期
跟入口组件生命周期差不太多,所有react中的生命周期都可以使用。还有以下生命周期
- onLoad (options),在小程序环境中对应页面的onLoad,在此声生命周期函数中,通过访问options参数,或者调用getCurrentInstance().router可以访问到页面的路由参数。
- onReady(),在小程序环境中对应页面的onReady(),从此生命周期开始时可以使用createCanvasContext或者createSelectQuery等API访问小程序渲染层的DOM节点。
只在页面组件才会触发 onReady 生命周期。子组件可以使用 Taro 内置的消息机制监听页面组件的 onReady() 生命周期。 - componentDidShow (),相当于小程序中的onShow(),页面显示/切入前台时触发。
只在页面组件才会触发 onShow 生命周期。子组件可以使用 Taro 内置的消息机制监听页面组件的 onShow() 生命周期: - componentDidHide (),相当于小程序中的onHide(),页面隐藏/切入后台时触发。
只在页面组件才会触发 onHide 生命周期。子组件可以使用 Taro 内置的消息机制监听页面组件的 onHide() 生命周期: - onPullDownRefresh (),监听用户下拉动作。
需要在全局配置的 window 选项中或页面配置中设置 enablePullDownRefresh: true。
可以通过 Taro.startPullDownRefresh 触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
当处理完数据刷新后,Taro.stopPullDownRefresh 可以停止当前页面的下拉刷新. - onReachBottom()。监听用户上拉触底事件。
可以在全局配置的 window 选项中或页面配置中设置触发距离 onReachBottomDistance。
在触发距离内滑动期间,本事件只会被触发一次。
H5 暂时没有同步实现,可以通过给 window 绑定 scroll 事件来进行模拟。 - onPageScroll (Object),监听用户滑动页面事件。 H5暂时没有同步实现,可以通过给window绑定scroll事件来进行模拟。
object参数为scrollTop,类型是Number,代表页面在垂直方向上已滚动的距离,单位为px。 - onAddToFavorites (Object),监听用户右上角菜单收藏按钮的行为,并可以自定义收藏内容。只有微信小程序支持,本接口为Beta版本。
参数object为webViewUrl,类型为string,当页面包含web-view组件时,会返回当前web-view的url。
此事件必须return一个object。用于自定义收藏内容:
onAddToFavorites (res) {
// webview 页面返回 webviewUrl
console.log('WebviewUrl: ', res?.webviewUrl)
return {
title: '自定义标题',
imageUrl: 'https://demo.png',
query: 'name=xxx&age=xxx',
}
}
- onShareAppMessage (Object),监听用户点击页面内转发按钮(Button 组件 openType=‘share’)或右上角菜单“转发”按钮的行为,并自定义转发内容。
当 onShareAppMessage 没有触发时,请在页面配置中设置 enableShareAppMessage: true
只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮
此事件必须return一个object。用于自定义转发内容:
export default class Index extends Component {
onShareAppMessage (res) {
if (res.from === 'button') {
// 来自页面内转发按钮
console.log(res.target)
}
return {
title: '自定义转发标题',
path: '/page/user?id=123'
}
}
}
- onShareTimeline ()
监听右上角菜单“分享到朋友圈”按钮的行为,并自定义分享内容。
Taro 3.0.3 版本开始支持 只有微信小程序支持,基础库 2.11.3 开始支持,本接口为 Beta 版本,暂只在 Android 平台支持
注意:
当 onShareTimeline 没有触发时,请在页面配置中设置 enableShareTimeline: true
只有定义了此事件处理函数,同时监听了 onShareAppMessage,右上角菜单才会显示“分享到朋友圈”按钮
返回值:
事件处理函数可以返回一个 Object,用于自定义分享内容,不支持自定义页面路径,返回内容如下:
class Index extends Component {
onShareAppMessage () {}
onShareTimeline () {
console.log('onShareTimeline')
return {}
}
}
-
onResize (Object),小程序屏幕旋转时触发。详见 响应显示区域变化。
-
onTabItemTap (Object),点击 tab 时触发。
参数如下: -
onTitleClick (),只有支付宝小程序支持,点击标题触发
-
onOptionMenuClick (),只有支付宝小程序支持,点击导航栏额外图标触发
-
onPopMenuClick (),只有支付宝小程序支持,点击右上角通用菜单中的自定义菜单按钮触发。
-
onPullIntercept (),只有支付宝小程序支持,下拉截断时触发。
内置组件
taro中可以使用小程序规范的内置组件进行开发,比如
<View>、<Text>、<Button>....
事件
事件和web端是一样的,在事件的回调函数中,第一个参数是事件对象,回调中调用stopProgapation阻止冒泡。
Taro规范
- 在react中使用内置组件时,必须要从@tarojs/components进行引入。 组件属性遵守大驼峰命名规范。
- 内置事件以on开头,遵从小驼峰命名规范。
比如点击事件为onClick。
只有小程序的 bindtap 对应 Taro 的 onClick
其余小程序事件名把 bind 换成 on 即是 Taro 事件名(支付宝小程序除外,它的事件就是以 on 开头) - 在小程序模板中,绑定事件都是以bind的形式。因此不能使用 e.stopPropagation() 阻止滚动穿透。
- 小程序模板中绑定的 catchtouchmove 事件除了可以阻止回调函数冒泡触发外,还能阻止视图的滚动穿透,这点 Taro 的事件系统是做不到的。
阻止滚动穿透
方式一:样式
Taro next自定义遮罩如何防止击穿
方式二:catchMove
地图组件本身就是可以滚动的,即使固定了它的宽高。所以第一种办法处理不了冒泡到地图组件上的滚动事件。
// 这个 View 组件会绑定 catchtouchmove 事件而不是 bindtouchmove
<View catchMove></View>
dataset
dataset是特别的模板属性,主要作用是可以在事件回调的event对象中获取到dataset相关数据。
在事件回调对象中可以通过 event.target.dataset 或 event.currentTarget.dataset 获取到。
生命周期触发函数
react中的所有生命周期函数都可以在taro中使用。
有两个稍微有些不同:
- componentWillMount()
在onload之后,组件渲染到taro的虚拟dom之前触发。 - componentDidMount()
组件渲染到taro的虚拟dom之后触发。
此时能访问到 Taro 的虚拟 DOM(使用 React ref、document.getElementById 等手段),并支持对其进行操作(设置 DOM 的 style 等)。
但此时不代表 Taro 的虚拟 DOM 数据已经完成从逻辑层 setData 到视图层。因此这时无法通过 createSelectorQuery 等方法获取小程序渲染层 DOM 节点。 只能在 onReady 生命周期中获取。
小程序页面的方法
- 小程序页面的方法,在 Taro 的页面中同样可以使用:在 Class Component 中书写同名方法、在 Functional
Component 中使用对应的 Hooks。 - 小程序页面方法在各端的支持程度不一。
- 使用了 HOC 包裹的小程序页面组件,必须处理
forwardRef 或使用继承组件的方式而不是返回组件的方式,否则小程序页面方法可能不会被触发。
Ref
在 Taro 中 ref 的用法和 React 完全一致,但是获取到的 “DOM” 和浏览器环境还有小程序环境都有不同。
React Ref
使用react ref获取到的是taro的虚拟dom,和浏览器的dom相似,可以操作它的style,调用它的api等。
但是taro的虚拟dom运行在小程序的逻辑层,并不是真实的小程序渲染层节点。
import React, { createRef } from 'react'
import { View } from '@tarojs/components'
export default class Test extends React.Component {
el = createRef()
componentDidMount () {
// 获取到的 DOM 具有类似 HTMLElement 或 Text 等对象的 API
console.log(this.el.current)
}
render () {
return (
<View id='only' ref={this.el} />
)
}
}
获取小程序的dom
获取真实的小程序渲染层节点,需要在 onReady 生命周期中,调用小程序中用于获取 DOM 的 API。
import React from 'react'
import { View } from '@tarojs/components'
import Taro from '@tarojs/taro'
export default class Test extends React.Component {
onReady () {
// onReady 触发后才能获取小程序渲染层的节点
Taro.createSelectorQuery().select('#only')
.boundingClientRect()
.exec(res => console.log(res))
}
render () {
return (
<View id='only' />
)
}
}
Minified React error
因为 development 版本的 React 体积较大,为了减少小程序体积,方便开发时真机预览。Taro 在构建小程序时默认使用 production 版本的 React 相关依赖。
但是 production 版本的 React 出错时不会展示报错堆栈的信息。因此当你遇到类似这种报错时:【Error: Minified React error #152】。可以修改编译配置中的 mini.debugReact 选项,然后重新开启编译。这样 Taro 会使用 development 版本的 React,从而输出报错堆栈。
其他限制
- 由于小程序不支持动态引入,因此小程序中无法使用 React.lazy API。
- 不能在页面组件的 DOM 树之外插入元素,因此不支持。
- 所有组件的 id 必须在整个应用中保持唯一(即使他们在不同的页面),否则可能导致事件不触发的问题,
更多推荐
所有评论(0)