Taro
第一章:初识
一、是什么
Taro 是一个开放式跨端跨框架解决方案,支持使用 React / Vue / Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 / 快手 小程序 / H5 / RN / ASCF元服务 等应用。
二、安装及使用
1)安装
# 使用 npm 安装 CLI
npm install -g @tarojs/cli2)项目初始化
taro init myApp更加现代的创建工程的方式
npx @tarojs/cli init myApp注意:npx 创建工程是不用安装 @tarojs/cli 的。
3)依赖安装
默认创建工程时会自动安装好依赖,如果安装失败,请执行 npm install 重新安装。
4)编译运行
Taro 编译分为 dev 和 build 模式:
- dev 模式(增加 --watch 参数)将会监听文件修改。
- build 模式(去掉 --watch 参数)将不会监听文件修改,并会对代码进行压缩打包。
dev 模式生成的文件较大,设置环境变量 NODE_ENV 为 production 可以开启压缩,方便预览,但编译速度会下降。
运行微信小程序
# npm script
npm run dev:weapp
npm run build:weapp
# 仅限全局安装
taro build --type weapp --watch
taro build --type weapp
# npx
npx taro build --type weapp --watch
npx taro build --type weapp
# watch 同时开启压缩
set NODE_ENV=production && taro build --type weapp --watch # CMD
NODE_ENV=production taro build --type weapp --watch # Bash运行 H5
# npm script
npm run dev:h5
npm run build:h5
# 仅限全局安装
taro build --type h5 --watch
taro build --type h5
# npx 用户也可以使用
npx taro build --type h5 --watch
npx taro build --type h5三、目录结构
├── dist 编译结果目录
|
├── config 项目编译配置目录
| ├── index.js 默认配置
| ├── dev.js 开发环境配置
| └── prod.js 生产环境配置
|
├── src 源码目录
| ├── pages 页面文件目录
| | └── index index 页面目录
| | ├── index.js index 页面逻辑
| | ├── index.css index 页面样式
| | └── index.config.js index 页面配置
| |
| ├── app.js 项目入口文件
| ├── app.css 全局的样式
| └── app.config.js 项目入口配置
|
├── project.config.json 微信小程序项目配置 project.config.json
├── project.tt.json 抖音小程序项目配置 project.tt.json
├── project.swan.json 百度小程序项目配置 project.swan.json
├── project.qq.json QQ 小程序项目配置 project.qq.json
├── ascf.config.json ASCF元服务项目配置 ascf.config.json
|
├── babel.config.js Babel 配置
├── tsconfig.json TypeScript 配置
├── .eslintrc ESLint 配置
|
└── package.json第二章:配置
一、重要配置文件
app.config.js 文件用来对小程序进行全局配置,配置项遵循微信小程序规范,并且对所有平台进行统一。
1. 通用配置项
1)pages
用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径 + 文件名 信息。文件名不需要写文件后缀。
数组的第一项代表小程序的初始页面(首页)。小程序中新增 / 减少页面,都需要对 pages 数组进行修改。
如开发目录为:
├── app.js
├── app.json
├── app.wxss
├── pages
│ │── index
│ │ ├── index.wxml
│ │ ├── index.js
│ │ ├── index.json
│ │ └── index.wxss
│ └── logs
│ ├── logs.wxml
│ └── logs.js
└── utils则需要在入口文件配置中写
export default {
pages: ['pages/index/index', 'pages/logs/logs'],
}2)window
用于设置小程序的状态栏、导航条、标题、窗口背景色,其配置项如下。
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| navigationBarBackgroundColor | HexColor(十六进制颜色值) | #000000 | 导航栏背景颜色,如 #000000 |
| navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black / white |
| navigationBarTitleText | String | 导航栏标题文字内容 | |
| navigationStyle | String | default | 导航栏样式,仅支持以下值:default 默认样式;custom 自定义导航栏,只保留右上角胶囊按钮 |
| backgroundColor | String | 窗口的背景色 | |
| backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
| enablePullDownRefresh | boolean | false | 是否开启当前页面的下拉刷新。 |
| onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为 px |
3)tabBar
| 属性 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| color | HexColor(十六进制颜色值) | 是 | tab 上的文字默认颜色,仅支持十六进制颜色 | |
| selectedColor | HexColor(十六进制颜色值) | 是 | tab 上的文字选中时的颜色,仅支持十六进制颜色 | |
| backgroundColor | HexColor(十六进制颜色值) | 是 | tab 的背景色,仅支持十六进制颜色 | |
| borderStyle | String | 是 | black | tabbar 上边框的颜色, 仅支持 black / white |
| list | Array | 是 | tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab | |
| position | String | 否 | bottom | tabBar 的位置,仅支持 bottom / top |
| custom | Boolean | 否 | false | 自定义 tabBar |
其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| pagePath | String | 是 | 页面路径,必须在 pages 中先定义 |
| text | String | 是 | tab 上按钮文字 |
| iconPath | String | 否 | 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。 |
| selectedIconPath | String | 否 | 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。 |
2. 页面配置
每一个小程序页面都可以使用 .config.js 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖全局配置 app.config.json 的 window 中相同的配置项。
.config.js 特有配置:
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| transparentTitle | String | none | 导航栏透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明 |
| disableScroll | Boolean | false | 设置为 true 则页面整体不能上下滚动。 只在页面配置中有效,无法在 app.json 中设置 |
| disableSwipeBack | Boolean | false | 禁止页面右滑手势返回 |
| enableShareAppMessage | Boolean | false | 是否启用分享给好友。 |
| enableShareTimeline | Boolean | false | 是否启用分享到朋友圈。 |
| usingComponents | Object | 否 | 页面自定义组件配置 |
3. 项目配置
为了能够适配不同小程序平台的配置文件不同的情况,Taro 支持为各个小程序平台添加各自的项目配置文件。
通过 Taro 模板创建的项目都会默认拥有 project.config.json 这一项目配置文件,这个文件只能用于微信小程序。
若要兼容到其他小程序平台,请按如下对应规则来增加相应平台的配置文件,其配置与各自小程序平台要求的一致:
| 小程序平台 | 添加配置文件 |
|---|---|
| 微信小程序 | project.config.json |
| 百度小程序 | project.swan.json |
| 抖音小程序 | project.tt.json |
| QQ 小程序 | project.qq.json |
| 支付宝小程序 | project.alipay.json |
| 飞书小程序 | project.lark.json |
| ASCF元服务 | ascf.config.json |
各类小程序平台均有自己的项目配置文件,例如:
微信小程序:project.config.json
抖音小程序:project.config.json
支付宝小程序:mini.project.json
4. 入口文件
@/app.js
class App extends Component {
// 1.组件生命周期
componentDidMount() {
console.log("app componentDidMount");
}
// 2.应用App的生命周期
onLaunch() {
console.log("app onLaunch");
}
componentDidShow() {
console.log("app componentDidShow");
}
componentDidHide() {
console.log("app componentDidHide");
}
// 3.定义全局数据
taroGlobalData = {
name: "liujun",
age: 18,
id: 1010,
};
render() {
// this.props.children 是将要会渲染的页面
return this.props.children;
}
}
export default App;使用全局数据 @/src/pages/home.jsx
export default class Home extends Component {
componentDidMount() {
const app = Taro.getApp(); // 不需要这样写:app.globalData.name
console.log(app.name);
console.log(app.age);
console.log(app.id);
}
render() {
return (
<View className="home">
<Text>Hello world!</Text>
</View>
);
}
}二、编译配置
编译配置存放于项目根目录下的 config 目录中,只要确保 config/index.js 或者 config/index.ts 文件存在,可以作为用户自定义编译配置导出即可。你也可以选择拆分成三个文件:
index.js是通用配置dev.js是项目预览时的配置prod.js是项目打包时的配置
详细的编译配置文档请查阅:编译配置详情
常用的配置
projectName 项目名称
date 项目创建时间
designWidth 设计稿尺寸
sourceRoot 项目源码目录
outputRoot 代码编译后的生产目录
defineConstants 用于配置一些全局变量, 供业务代码中进行使用
alias 配置路径别名
h5.webpackChain webpack 配置
h5.devServer 开发者服务配置
env 设置环境变量
plugins 配置 Taro 插件
framework 使用的开发框架
compiler 使用的编译工具第三章:组件
来源
官方文档:组件库说明
一、视图容器
1. View
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| hoverClass | string | none | 否 | 指定按下去的样式类。当 hover-class="none" 时,没有点击态效果 |
| hoverStopPropagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 |
| hoverStartTime | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 |
| hoverStayTime | number | 400 | 否 | 手指松开后点击态保留时间,单位毫秒 |
| hidden | boolean | false | 否 | 是否隐藏。 |
2. Text
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| selectable | boolean | false | 否 | 文本是否可选 |
| userSelect | boolean | false | 否 | 文本是否可选,该属性会使文本节点显示为 inline-block |
| space | keyof TSpace | 否 | 显示连续空格 | |
| decode | boolean | false | 否 | 是否解码 |
| numberOfLines | number | 否 | 多行省略,值须大于等于 1,表现同 css 的 -webkit-line-clamp 属性一致。 | |
| overflow | keyof Overflow | 'visible' | 否 | 文本溢出处理 |
| maxLines | number | 否 | 限制文本最大行数 |
TSpace
space 的合法值。
| 参数 | 说明 |
|---|---|
| ensp | 中文字符空格一半大小 |
| emsp | 中文字符空格大小 |
| nbsp | 根据字体设置的空格大小 |
Overflow
| 参数 | 说明 |
|---|---|
| clip | 修剪文本 |
| fade | 淡出 |
| ellipsis | 显示省略号 |
| visible | 文本不截断 |
3. Swiper
SwiperItem 宽高自动设置为 100%。
Swiper 组件支持的 Props
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| indicatorDots | boolean | false | 否 | 是否显示面板指示点 |
| indicatorColor | string | "rgba(0, 0, 0, .3)" | 否 | 指示点颜色 |
| indicatorActiveColor | string | "#000000" | 否 | 当前选中的指示点颜色 |
| autoplay | boolean | false | 否 | 是否自动切换 |
| current | number | 0 | 否 | 当前所在滑块的 index |
| currentItemId | string | "" | 否 | 当前所在滑块的 item-id ,不能与 current 被同时指定 |
| interval | number | 5000 | 否 | 自动切换时间间隔 |
| duration | number | 500 | 否 | 滑动动画时长 |
| circular | boolean | false | 否 | 是否采用衔接滑动 |
| vertical | boolean | false | 否 | 滑动方向是否为纵向 |
| displayMultipleItems | number | 1 | 否 | 同时显示的滑块数量 |
| indicatorMargin | number | 10 | 否 | 指示点四周边距 |
| indicatorSpacing | number | 4 | 否 | 指示点间距 |
| indicatorRadius | number | 4 | 否 | 指示点圆角大小 |
| indicatorWidth | number | 8 | 否 | 指示点宽度 |
| indicatorHeight | number | 8 | 否 | 指示点高度 |
| indicatorAlignment | string or [number, number] | auto | 否 | 指示点的相对位置 |
| indicatorOffset | [number, number] | [0, 0] | 否 | 指示点位置的偏移量 |
| scrollWithAnimation | boolean | true | 否 | 改变 current 时使用动画过渡 |
| onChange | CommonEventFunction<onChangeEventDetail> | 否 | current 改变时会触发 change 事件 |
4. ScrollView
可滚动视图区域。使用竖向滚动时,需要给 scroll-view 一个固定高度,通过 CSS 设置 height。
Tips: H5 中 ScrollView 组件是通过一个高度(或宽度)固定的容器内部滚动来实现的,因此务必正确的设置容器的高度。例如: 如果 ScrollView 的高度将 body 撑开,就会同时存在两个滚动条(body 下的滚动条,以及 ScrollView 的滚动条)。 微信小程序 中 ScrollView 组件如果设置 scrollX 横向滚动时,并且子元素为多个时(单个子元素时设置固定宽度则可以正常横向滚动),需要通过 WXSS 设置 white-space: nowrap 来保证元素不换行,并对 ScrollView 内部元素设置 display: inline-block 来使其能够横向滚动。
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| scrollX | boolean | false | 否 | 允许横向滚动 |
| scrollY | boolean | false | 否 | 允许纵向滚动 |
| upperThreshold | number | 50 | 否 | 距顶部/左边多远时(单位px),触发 scrolltoupper 事件 |
| lowerThreshold | number | 50 | 否 | 距底部/右边多远时(单位px),触发 scrolltolower 事件 |
| scrollTop | number | 否 | 设置竖向滚动条位置 | |
| scrollLeft | number | 否 | 设置横向滚动条位置 | |
| scrollWithAnimation | boolean | false | 否 | 在设置滚动条位置时使用动画过渡 |
| scrollAnimationDuration | string | 否 | 当 scroll-with-animation 设置为 true 时,可以设置 scroll-animation-duration 来控制动画的执行时间,单位 ms。 | |
| refresherEnabled | boolean | false | 否 | 开启自定义下拉刷新 |
| refresherThreshold | number | 45 | 否 | 设置自定义下拉刷新阈值 |
| refresherDefaultStyle | string | 'black' | 否 | 设置自定义下拉刷新默认样式,支持设置 black or white or none, none 表示不使用默认样式 |
| refresherBackground | string | '#FFF' | 否 | 设置自定义下拉刷新区域背景颜色 |
| refresherTriggered | boolean | false | 否 | 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发 |
| enhanced | boolean | false | 否 | 启用 scroll-view 增强特性 |
| showScrollbar | boolean | true | 否 | 滚动条显隐控制 (同时开启 enhanced 属性后生效) |
| pagingEnabled | boolean | false | 否 | 分页滑动效果 (同时开启 enhanced 属性后生效) |
| onScrollToUpper | CommonEventFunction | 否 | 滚动到顶部/左边,会触发 scrolltoupper 事件 | |
| onScrollToLower | CommonEventFunction | 否 | 滚动到底部/右边,会触发 scrolltolower 事件 | |
| onScroll | BaseEventOrigFunction<onScrollDetail> | 否 | 滚动时触发 | |
| onRefresherPulling | CommonEventFunction | 否 | 自定义下拉刷新控件被下拉 |
二、表单组件
1. Button
2. Checkbox
三、媒体组件
1. Image
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| src | string | 是 | 图片资源地址 | |
| mode | keyof Mode | "scaleToFill" | 否 | 图片裁剪、缩放的模式 |
| lazyLoad | boolean | false | 否 | 图片懒加载。只针对 page 与 scroll-view 下的 image 有效 |
| showMenuByLongpress | boolean | false | 否 | 开启长按图片显示识别小程序码菜单 |
| defaultSource | string | 否 | 默认图片地址,若设置默认图片地址,会先显示默认图片,等 src 对应的图片加载成功后,再渲染对应的图片。 | |
| onLoad | CommonEventFunction<onLoadEventDetail> | 否 | 当图片载入完毕时,发布到 AppService 的事件名,事件对象 | |
| onError | CommonEventFunction<onErrorEventDetail> | 否 | 当错误发生时,发布到 AppService 的事件名,事件对象 | |
| onTap | CommonEventFunction | 否 | 点击图片时触发。 | |
| catchTap | CommonEventFunction | 否 | 点击图片时触发,阻止事件冒泡。 |
四、导航
1. Navigator
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| url | string | 否 | 当前小程序内的跳转链接 | |
| openType | keyof OpenType | "navigate" | 否 | 跳转方式 |
| delta | number | 否 | 当 open-type 为 'navigateBack' 时有效,表示回退的层数 | |
| hoverClass | string | "navigator-hover" | 否 | 指定按下去的样式类。当 hover-class="none" 时,没有点击态效果 |
| hoverStopPropagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 |
| hoverStartTime | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 |
| hoverStayTime | number | 600 | 否 | 手指松开后点击态保留时间,单位毫秒 |
OpenType
open-type 的合法值。
| 参数 | 说明 |
|---|---|
| navigate | 对应 Taro.navigateTo 或 Taro.navigateToMiniProgram 的功能 |
| redirect | 对应 Taro.redirectTo 的功能 |
| switchTab | 对应 Taro.switchTab 的功能 |
| reLaunch | 对应 Taro.reLaunch 的功能 |
| navigateBack | 对应 Taro.navigateBack 的功能 |
| exit | 退出小程序,target="miniProgram" 时生效 |
第四章:CSS
一、基础
1. 设计稿及尺寸单位
在 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:
// `/config/index.js`
const config = {
designWidth: 640,
....
}目前 Taro 支持 750、640 、828 三种尺寸设计稿,他们的换算规则如下:
const DEVICE_RATIO = {
640: 2.34 / 2,
750: 1,
828: 1.81 / 2,
}建议使用 Taro 时,设计稿以 iPhone 6 750px 作为设计尺寸标准。
在编译时,Taro 会帮你对样式做尺寸转换操作,但是如果是在 JS 中书写了行内样式,那么编译时就无法做替换了,针对这种情况,Taro 提供了 API Taro.pxTransform 来做运行时的尺寸转换。
Taro.pxTransform(10) // 小程序:rpx,H5:rem2. CSS 编译时忽略(过滤)
1)忽略单个属性
当前忽略单个属性的最简单的方法,就是 px 单位使用大写字母。
/* `px` is converted to `rem` */
.convert {
font-size: 16px; // converted to 1rem
}
/* `Px` or `PX` is ignored by `postcss-pxtorem` but still accepted by browsers */
.ignore {
border: 1Px solid; // ignored
border-width: 2PX; // ignored
}2)忽略样式文件
对于头部包含注释 /*postcss-pxtransform disable*/ 的文件,插件不予处理。
二、CSS 冲突解决
1. 使用 CSS Modules
来源
官方文档:使用 CSS Modules
1)开启方法
在小程序端开启
weapp: {
module: {
postcss: {
// css modules 功能开关与相关配置
cssModules: {
enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true
config: {
namingPattern: 'module', // 转换模式,取值为 global/module,下文详细说明
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
}
}在 H5 端开启
h5: {
module: {
postcss: {
// css modules 功能开关与相关配置
cssModules: {
enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true
config: {
namingPattern: 'module', // 转换模式,取值为 global/module,下文详细说明
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
}
}2)设置转换模式
Taro 中使用 CSS Modules 有两种模式,分别为全局转换及部分自定义转换模式,通过 namingPattern 配置进行控制。
namingPattern 配置取值分别如下:
- global:表示全局转换,所有样式文件都会经过 CSS Modules 转换处理,除了文件名中包含
.global.的样式文件。 - module:表示自定义转换,只有文件名中包含
.module.的样式文件会经过 CSS Modules 转换处理。
generateScopedName 支持传入字符串和函数:
字符串,其格式见:https://github.com/webpack/loader-utils#interpolatename,值得指出的是,可使用[local]取其原类名函数,其类型定义为(localName: string, absoluteFilePath: string) => string,其中localName为原类名,absoluteFilePath为文件的绝对路径,返回值将作为新的类名
2. CSS-in-JS
来源
官方文档:使用 CSS-in-JS
第五章:React 页面
一、生命周期
1. 应用生命周期
来源
官方文档:生命周期方法
入口组件除了支持 React 的生命周期(组件生命周期)方法外,还根据小程序的标准,额外支持以下生命周期:
| 生命周期方法 | 解释 |
|---|---|
| onLaunch(options) | 在小程序环境中对应 app 的 onLaunch。 在此生命周期中通过访问 options 参数或调用 getCurrentInstance().router,可以访问到程序初始化参数。 |
| componentDidShow(options) | 程序启动,或切前台时触发。 |
| componentDidHide() | 程序切后台时触发。 |
| onError(error) | 小程序发生脚本错误或 API 调用报错时触发。 |
| onPageNotFound(Object) | 程序要打开的页面不存在时触发。 |
| onUnhandledRejection(Object) | 小程序有未处理的 Promise 拒绝时触发。 |
2. 页面生命周期
1)类式
来源
官方文档:React 页面组件
页面组件除了支持 React 的生命周期方法外,还根据小程序的标准,额外支持以下生命周期:
- onLoad(options):在此生命周期中通过访问 options 参数或调用
getCurrentInstance().router,可以访问到页面路由参数。 - componentDidShow():在小程序环境中对应页面的 onShow。页面显示 / 切入前台时触发。
- onReady():从此生命周期开始可以使用 createSelectorQuery 等 API 访问小程序渲染层的 DOM 节点。
- componentDidHide():在小程序环境中对应页面的 onHide。页面隐藏 / 切入后台时触发。
- onUnload():在小程序环境中对应页面的 onUnload。
- onPullDownRefresh():监听用户下拉动作。
- 需要在全局配置的 window 选项中或页面配置中设置
enablePullDownRefresh: true。 - 可以通过 Taro.startPullDownRefresh 触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
- 当处理完数据刷新后,Taro.stopPullDownRefresh 可以停止当前页面的下拉刷新。
- 需要在全局配置的 window 选项中或页面配置中设置
- onReachBottom():监听用户上拉触底事件。
- 可以在全局配置的 window 选项中或页面配置中设置触发距离 onReachBottomDistance。
- 需要 enablePullDownRefresh 配置。
- onPageScroll(Object):监听用户滑动页面事件。
- Object 接收一个 scrollTop 数值类型的参数,告知页面在垂直方向已滚动的距离(单位 px)。
- 需要 enablePullDownRefresh 配置。
2)Hooks
来源
官方文档:React Hooks
在 Taro 中使用 Hooks API 很简单,Taro 的专有 Hooks(例如 usePageScroll, useReachBottom)从 @tarojs/taro 中引入,框架自己的 Hooks (例如 useEffect, useState)从对应的框架引入。
import { usePageScroll, useReachBottom } from '@tarojs/taro' // Taro 专有 Hooks
import { useState, useEffect } from 'react' // 框架 Hooks (基础 Hooks)3. 组件生命周期
React 中的生命周期。
四、页面通讯
方法一:全局数据
在 App.js 中存放数据。
方式二:本地数据存储
使用数据缓存 API 来存放数据。
方式三:Redux 状态管理库
方式四:路由传参
url 查询字符串。


方法五:事件总线
来源
import Taro from '@tarojs/taro'
Taro.eventCenter.on(事件名, 回调函数)
Taro.eventCenter.trigger(事件名, 数据)
Taro.eventCenter.off(事件名, 回调函数)例子
Home 组件中,监听了一个 acceptDataFormDatailPage 全局事件。
export default class Home extends Component {
acceptDataFormDatailPage(data) {
console.log(data);
}
onLoad() {
// 监听
Taro.eventCenter.on(
"acceptDataFormDatailPage",
this.acceptDataFormDatailPage
);
}
onUnload() {
// 取消监听
Taro.eventCenter.off(
"acceptDataFormDatailPage",
this.acceptDataFormDatailPage
);
}
goToDetail() {
Taro.navigateTo({
url: "/pages/detail/index",
});
}
render() {
return (
<View className="home">
<Button onClick={() => this.goToDetail()}>
goToDetail navigate
</Button>
</View>
);
}
}Detail 中在合适的时机触发了 acceptDataFormDatailPage 全局事件。
export default class Detail extends Component {
goBack() {
Taro.navigateBack({
delta: 1,
});
// 触发一个全局事件
Taro.eventCenter.trigger("acceptDataFormDatailPage", {
data: "将detail的数据传递到home页面",
});
}
render() {
return (
<View className="detail">
<Button onClick={() => this.goBack()}>返回</Button>
</View>
);
}
}方法六:EventChannel
来源
官方文档:EventChannel
注意:只支持小程序端。
export default class Detail extends Component {
$instance = Taro.getCurrentInstance(); // 是可以拿到当前的app实例,page实例和router对象
// 页面生命周期
onLoad(options) {
// 下面的代码只兼容微信小程序
if (process.env.TARO_ENV === "weapp") {
// const pages = Taro.getCurrentPages()
// const page = pages[pages.length - 1]
// const eventChannel = page.getOpenerEventChannel();
const eventChannel = this.$instance.page.getOpenerEventChannel();
eventChannel.on("acceptDataFromHomePage", function (data) {
console.log(data);
});
}
}
goBack() {
Taro.navigateBack({
delta: 1,
});
if (process.env.TARO_ENV === "weapp") {
// 注意:这中方式只支持微信小程序端
const eventChannel = this.$intance.page.getOpenerEventChannel();
eventChannel.emit("acceptDataFromDetailPage", {
data: "拿到detail传递到home页面的数据",
});
}
}
render() {
return (
<View className="detail">
<View>detail</View>
<Button onClick={() => this.goBack()}>返回</Button>
</View>
);
}
}在想要触发 acceptDataFromHomePage 回调的地方使用 emit 方法。
goToDetail() {
Taro.navigateTo({
url: "/pages/detail/index?name=yxts&id=100",
success: function (res) {
if (process.env.TARO_ENV === "weapp") {
// 注意:这中方式只支持微信小程序端
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit("acceptDataFromHomePage", {
data: "我是从home页面传递到detail的数据",
});
}
},
events: {
// 注意:这中方式只支持微信小程序端
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromDetailPage: function (data) {
console.log(data);
},
});
}第六章:API
一、框架
1. getApp
Taro.getApp(opts):获取到小程序全局唯一的 App 实例。
2. getCurrentPages
Taro.getCurrentPages():获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。
3. getCurrentInstance
Taro.getCurrentInstance():获取当前页面实例。
二、界面
1. 交互
1)提示框
Taro.showToast(option)
Taro.hideToast(option):隐藏消息提示框。
2)loading 提示框
Taro.showLoading(option):显示 loading 提示框。需主动调用 Taro.hideLoading 才能关闭提示框。
Taro.hideLoading(option):隐藏 loading 提示框。
3)模态对话框
Taro.showModal(option)
5)操作菜单
Taro.showActionSheet(option)
2. 导航栏
Taro.setNavigationBarTitle(option):动态设置当前页面的标题。
Taro.hideHomeButton(option):隐藏返回首页按钮。
三、网络请求
1. request
Taro.request(option)
data 参数说明:最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下:
- 对于 GET 方法的数据,会将数据转换成 query string。
- 对于 POST 方法且
header['content-type']为application/json的数据,会对数据进行 JSON 序列化 - 对于 POST 方法且
header['content-type']为application/x-www-form-urlencoded的数据,会将数据转换成 query string。
option 可用选项:option 可传入参数说明
对网络请求 API 进行封装:
import Taro from "@tarojs/taro";
const TIME_OUT = 60000;
const BASE_URL = "http://111.111.111.111:8080/v1";
class DDFRequest {
request(url, method = "GET", data = {}) {
return new Promise((resolve, reject) => {
Taro.request({
url: BASE_URL + url,
method: method || "GET",
timeout: TIME_OUT,
data: data,
success(res) {
resolve(res.data);
},
fail(err) {
reject(err);
},
});
});
}
get(url, params = {}) {
return this.request(url, "GET", params);
}
post(url, data = {}) {
return this.request(url, "POST", data);
}
}
export default new DDFRequest();四、数据缓存
来源
官方文档:数据缓存
五、路由
来源
官方文档:路由
1. 重要操作
1)获取路由参数
React 类式组件中:
export default class Detail extends Component {
$instance = Taro.getCurrentInstance(); // 是可以拿到当前的app实例,page实例和router对象
// 页面生命周期
onLoad(options) {
// 方式一:拿到页面传递过来的url参数
console.log("Detail=>", options);
}
componentDidShow() {
// 方式二: 拿到页面传递过来的url参数
console.log("Detail=>", this.$instance.router.params);
}
render() {
return (
<View className="detail">
<Text>detail</Text>
</View>
);
}
}React 函数式组件中:
const Detail = function () {
// 方式一:拿到页面传递过来的url参数
// 为什么使用useRef?因为useRef存的对象在整个组件的生命周期中都是保持同一个对象
const $instance = useRef(Taro.getCurrentInstance());
console.log("router.params=>", $instance.current.router.params);
// 方式二: 拿到页面传递过来的url参数
useLoad((options) => {
console.log("Detail=>", options);
})
return (
<View className="detail"></View>
);
};
export default Detail;第七章:其他杂项
一、跨端兼容方案
来源
官方文档:跨平台开发
1. 内置环境变量
process.env.TARO_ENV 用于判断当前的编译平台类型。
取值:weapp / swan / alipay / tt / qq / jd / h5 / rn/ ascf
可以通过这个变量来区分不同环境,从而使用不同的逻辑。在编译阶段,会移除不属于当前编译类型的代码,只保留当前编译类型下的代码,例如:
① 在微信小程序和 H5 端分别引用不同资源:
/** 源码 */
if (process.env.TARO_ENV === 'weapp') {
require('path/to/weapp/name')
} else if (process.env.TARO_ENV === 'h5') {
require('path/to/h5/name')
}
/** 编译后(微信小程序)*/
if (true) {
require('path/to/weapp/name')
}
/** 编译后(H5)*/
if (true) {
require('path/to/h5/name')
}② 决定不同端要加载的组件
/** 源码(React JSX) */
<View>
{process.env.TARO_ENV === 'weapp' && <ScrollViewWeapp />}
{process.env.TARO_ENV === 'h5' && <ScrollViewH5 />}
</View>
/** 编译后(微信小程序)*/
<View>
{true && <ScrollViewWeapp />}
</View>
/** 编译后(H5)*/
<View>
{true && <ScrollViewH5 />}
</View>2. 条件编译
为了方便大家书写样式跨端的组件代码,目前在 .vue 文件 template 模板内容中支持条件编译的特性。
指定平台保留样式:
/* #ifdef %PLATFORM% */
模板代码
/* #endif */指定平台剔除样式:
/* #ifndef %PLATFORM% */
模板代码
/* #endif */其中 PLATFORM 的取值与 process.env.TARO_ENV 保持一致。
例如,希望某段模板内容只在微信小程序中 生效。
/* #ifdef weapp */
模板代码
/* #endif */如果是多个平台,之间可以使用空格隔开。
3. 统一接口的多端文件
将文件修改成 原文件名 + 端类型 的命名形式(端类型对应着 process.env.TARO_ENV 的取值),不同端的文件代码对外保持统一接口,而引用的时候仍然是 import 原文件名的文件。Taro 在编译时,会跟根据当前的编译平台类型,将加载的文件变更为带有对应端类型文件名的文件,从而达到不同的端加载对应文件的目的。
4. 多端同步调试
从 1.3.5 版本开始,可以在 dist 目录下创建一个与编译的目标平台名同名的目录,并将结果放在这个目录下,例如编译到微信小程序,最终结果是在 dist/weapp 目录下,这样做的好处是,各个平台使用独立的目录互不影响,从而达到多端同步调试的目的,在 config/index.js 配置如下:
outputRoot: `dist/${process.env.TARO_ENV}`对于微信小程序,还需要将 project.config.json 文件的 miniprogramRoot 的值改为 dist/weapp/,这样就可以正常在开发者工具中看到小程序了。
二、Redux & RTK
与在 React 中使用一致。
附加
一、推荐阅读
