Taro多端小程序学习笔记

本文最后更新于:1 年前

Taro 多端小程序学习笔记

快速搭建项目

项目初始化以及配置推荐看Taro官网更详细

安装

1
2
3
4
5
6
7
8
# 使用 npm 安装 CLI
npm install -g @tarojs/cli

# OR 使用 yarn 安装 CLI
yarn global add @tarojs/cli

# OR 安装了 cnpm,使用 cnpm 安装 CLI
cnpm install -g @tarojs/cli

查看 Taro 全部版本信息

1
npm info @tarojs/cli

项目初始化

1
taro init myApp

编译运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
npm run dev:h5 //H5小程序
npm run build:h5

npm run dev:weapp //微信小程序
npm run build:weapp

npm run dev:swan //百度小程序
npm run build:swan

npm run dev:alipay //支付宝小程序
npm run build:alipay

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

npm run dev:qq //QQ小程序
npm run build:qq

npm run dev:jd //京东小程序
npm run build:jd

......

项目结构

项目目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
├── 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.config.json
├── project.swan.json 百度小程序项目配置 project.swan.json
├── project.qq.json QQ 小程序项目配置 project.config.json
|
├── babel.config.js Babel 配置
├── tsconfig.json TypeScript 配置
├── .eslintrc ESLint 配置
|
└── package.json

编译配置

1
2
3
4
└── config                      项目编译配置目录
├── index.js 默认配置
├── dev.js 开发环境配置
└── prod.js 生产环境配置

源码组织

app
1
2
3
4
└── src                         源码目录
├── app.js 项目入口文件
├── app.css 项目总通用样式
└── app.config.js 项目入口配置

小程序的主体由下面三个文件组成:

文件 必须 作用
app.js 小程序入口逻辑
app.css 小程序全局样式
app.config.js 小程序全局配置
page
1
2
3
4
5
6
└── src                         源码目录
└── pages 页面文件目录
└── index index 页面目录
├── index.js index 页面逻辑
├── index.css index 页面样式
└── index.config.js index 页面配置

一个小程序页面由三个文件组成,如下:

文件 必须 作用
page.js 页面入口逻辑
page.css 页面样式
page.config.js 页面配置
项目配置
1
└──project.config.json         微信小程序项目配置 project.config.json
Babel 配置
1
└── babel.config.js             Babel 配置
ESLint 配置
1
└── .eslintrc                   ESLint 配置

组件

组件的使用

taro 的组件使用支持 react 的组件方式,如果使用 taro 创建组件会报错。
child.jsx 子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Component } from "@tarojs/taro";
import { View, Text } from "@tarojs/components";
class Child extends Component {
render() {
return <View>我是Child组件</View>;
}
}
export default Child;
//或者
import Taro, { Component } from "@tarojs/taro";
import { View, Text } from "@tarojs/components";
class Child extends Taro.Component {
render() {
return <View>我是Child组件</View>;
}
}
export default Child;

//这两种方式都会报错

Error: TypeError: Super expression must either be null or a function
image.png
所以推荐使用 react 创建组件的方式
child.jsx 子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from "react";
import { View, Text } from "@tarojs/components";
class Child extends React.Component {
render() {
return <View>我是Child组件</View>;
}
}
export default Child;
//或者
import { Component } from "react";
import { View, Text } from "@tarojs/components";
class Child extends Component {
render() {
return <View>我是Child组件</View>;
}
}
export default Child;


父子组件传值

父子组件通过 props 传递数据,子组件不能修改,只能接收父组件的数据
父组件在组件内部设置一个属性传递给子组件
src\pages\index\index.jsx 父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'
import Child from './child'

export default class Index extends Component {
state = {
text: { username: '李四' },
}
render() {
console.log('render...')
return (
<View className='index'>
{/* <Child></Child> */}
<Child text={this.state.text}></Child>
</View>
)
}
}

src\pages\index\child.jsx 子组件

1
2
3
4
5
6
7
8
9
10
import { Component } from 'react'
import { View, Text } from '@tarojs/components'

class Child extends Component {
render() {
const { text } = this.props
return <View>我是Child组件{text.username}</View>
}
}
export default Child

设置默认属性

如果父组件没有传递任何属性,可以在子组件通过Child.defaultProps={}设置默认属性
src\pages\index\index.jsx 父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'
import Child from './child'

export default class Index extends Component {
render() {
return (
<View className='index'>
<Child></Child>
</View>
)
}
}

src\pages\index\child.jsx 子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Component } from 'react'
import { View, Text } from '@tarojs/components'

class Child extends Component {
render() {
const { text } = this.props
return <View>我是Child组件{text.username}</View>
}
}
//设置默认属性 如果父组件没有传递属性给子组件
Child.defaultProps = {
text: { username: '111111' },
}
export default Child

常用生命周期

componentWillMount( )

componentWillMount( ) 组件挂载之前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
componentWillMount() {
console.log('组件挂载之前,componentWillMount')
}
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}

componentDidMount( )

componentDidMount( ) 组件挂载之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
state = {
text: "张三",
age: 10,
};
componentDidMount () {
componentDidMount() {
console.log("组件挂载之后,componentDidMount");
//更改组件状态
//想要获取最新的状态,需要在setSate的第二个参数函数内部获取
this.setState(
{
text: "李四",
},
() => {
console.log(2, this.state.text); //李四 同步最新的状态
}
);
console.log(1, this.state.text); //张三 异步更新还是更改之前的状态
}
}
render () {
return (
<View className='index'>
<Text>{this.state.text}</Text>
<Text>{this.state.age}</Text>
</View>
)
}
}

注意更改 state 只能用 setState,但是 setState 是异步更新。在 setState 之后获取的值是更改之前的值,想要得到最新的值只能在 setState 的第二个参数中的回调函数中拿到最新值

setState 更新最新数据
1
2
3
4
5
6
7
8
9
10
this.setState(
{
text: '李四', //更改的值
},
() => {
//在第二个参数的回调函数中拿到最新的值
console.log(2, this.state.text) //李四 同步最新的状态
}
)
console.log(1, this.state.text) //张三 异步更新还是更改之前的状态

componentWillUnmount( )

componentWillUnmount( ) 组件销毁时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
componentWillUnmount() {
console.log('组件销毁时,componentWillUnmount')
}
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}

componentDidShow( )

componentDidShow( ) 页面显示的时候,在 react 中不存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
componentDidShow() {
//react中不存在
console.log('页面显示的时候,componentDidShow')
}
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}

componentWillHide( )

componentWillHide( ) 页面隐藏的时候,在 react 中不存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
componentWillHide() {
//react中不存在
console.log('页面隐藏的时候,componentDidHide')
}
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}

componentWillUpdate( )

componentWillUpdate( ) state 数据将要更新之前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
componentWillUpdate() {
console.log('state数据将要更新之前,componentWillUpdate')
}
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}

componentDidUpdate( )

componentDidUpdate( ) state 数据将要更新之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
componentDidUpdate() {
console.log('state数据更新之后,componentDidUpdate')
}
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}

shouldComponentUpdate(nextProps, nextState)

shouldComponentUpdate(nextProps, nextState) 检查此次 setState 是否进行 render 调用 默认返回 true,一般用来多次的 setState 调用时,提升 render 的性能。只需要判断最后一次是否修改 然后返回 true,再进行 render 渲染
两个参数 nextState 最新的状态,nextProps 最新的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {
state = {
text: "张三",
age: 10,
};
componentDidMount () {
componentDidMount() {
console.log("组件挂载之后,componentDidMount");
//更改组件状态
//想要获取最新的状态,需要在setSate的第二个参数函数内部获取
this.setState(
{
text: "李四",
},
() => {
console.log(2, this.state.text); //李四 同步最新的状态
}
);
console.log(1, this.state.text); //张三 异步更新还是更改之前的状态
}
}
shouldComponentUpdate(nextProps, nextState) {
//检查此次setState是否进行render调用 默认返回true
//一般用来多次的setState调用时,提升render的性能
// console.log("shouldComponentUpdate", nextState.text); //nextState最新的状态,nextProps最新的属性
if (nextState.text === "李四") return true;
else return false;
}
render () {
return (
<View className='index'>
<Text>{this.state.text}</Text>
<Text>{this.state.age}</Text>
</View>
)
}
}

componentWillReceiveProps(nextProps, nextState)

componentWillReceiveProps(nextProps, nextState) 父组件传递给子组件的属性发送变化的时候,此钩子函数才会执行,初始化的时候不会执行。nextProps 才是最新的属性
src\pages\index\index.jsx 父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'
import Child from './child'
export default class Index extends Component {
state = {
text: { username: '李四' },
}
componentDidMount() {
//更改组件的状态
this.setState({
text: { username: '王五' },
})
}
render() {
return (
<View className='index'>
<Child text={this.state.text}></Child>
</View>
)
}
}

src\pages\index\child.jsx 子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
class Child extends Component {
//初始化的时候不会执行
//父组件传递给子组件的属性发送变化的时候,此钩子函数才会执行
componentWillReceiveProps(nextProps, nextState) {
// console.log(this.props.text.username); //这里还是以前的属性
console.log(nextProps.text.username) //nextProps才是最新的属性
}
render() {
const { text } = this.props
return <View>我是Child组件{text.username}</View>
}
}
export default Child

路由

基本路由配置

src\pages\test\test.jsx 新建一个文件以及配置文件 test.config.js

1
2
3
4
5
6
7
8
9
import { Component } from 'react'
import { View, Text } from '@tarojs/components'

export default class Index extends Component {
render() {
console.log('render...')
return <View className='index'>test!!</View>
}
}

src\app.config.js 配置默认路径

1
2
3
4
5
6
7
8
9
export default {
pages: ['pages/test/test', 'pages/index/index'],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: 'WeChat',
navigationBarTextStyle: 'black',
},
}

"pages/test/test"写在数组前面就是默认路径,然后重启项目

基本页面跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Component } from 'react'
import { View, Text, Button } from '@tarojs/components'
import Taro from '@tarojs/taro'
export default class Index extends Component {
handleClick() {
//保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。
//使用 Taro.navigateBack 可以返回到原页面。小程序中页面栈最多十层。
//相当于 h5:$router.push
Taro.navigateTo({
url: '/pages/index/index',
})
}
render() {
return (
<View className='index'>
<Button onClick={this.handleClick}>test!!</Button>
</View>
)
}
}
redirectTo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Component } from 'react'
import { View, Text, Button } from '@tarojs/components'
import Taro from '@tarojs/taro'
export default class Index extends Component {
handleClick() {
//关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
//相当于 h5:$router.replace
Taro.redirectTo({
url: '/pages/index/index',
})
}
render() {
return (
<View className='index'>
<Button onClick={this.handleClick}>test!!</Button>
</View>
)
}
}

路由传参

src\pages\test\test.jsx 发送参数的页面,将参数拼接到 url 上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Component } from 'react'
import { View, Text, Button } from '@tarojs/components'
import Taro from '@tarojs/taro'

export default class Index extends Component {
handleClick() {
//关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
//相当于 h5:$router.replace
Taro.redirectTo({
url: '/pages/index/index?id=1',
})
}
render() {
return (
<View className='index'>
<Button onClick={this.handleClick}>test!!</Button>
</View>
)
}
}

src\pages\index\index.jsx 接收参数的页面,const id = this.$router.params.id;//已经失效 taro3 有更新用getCurrentInstance()
taro3 中更新开发中我们常常会调用 Taro.getCurrentInstance() 获取小程序的 app、page 对象、路由参数等数据。但频繁调用它可能会导致问题。把 Taro.getCurrentInstance() 的结果在组件中保存起来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { Component } from 'react'
import { View, Text } from '@tarojs/components'
import './index.less'
import Child from './child'
import Taro from '@tarojs/taro'

export default class Index extends Component {
state = {
text: { username: '李四' },
}
componentWillMount() {
//获取到test页面传递过来的参数
// const id = this.$router.params.id;//已经失效taro3有更新用getCurrentInstance()
//taro3中更新开发中我们常常会调用 Taro.getCurrentInstance() 获取小程序的 app、page 对象、路由参数等数据。
//但频繁调用它可能会导致问题。把 Taro.getCurrentInstance() 的结果在组件中保存起来
const id = Taro.getCurrentInstance().router.params.id
console.log(id)
}
render() {
return (
<View className='index'>
{/* <Child></Child> */}
<Child text={this.state.text}></Child>
</View>
)
}
}

导出资源以及导入方式

导入模块

方法一

单独导出
src\util.js

1
2
3
4
5
6
export function setData() {
console.log("setData");
}
export function getData() {
console.log("getData");
}

解构赋值引入
src\pages\test\test.jsx

1
import { setData , getData } from "../../util";

如果是 export 单独导出,则解构赋值方法引入

方法二

默认方式导出

1
2
3
4
5
6
7
function setData() {
console.log("setData");
}
function getData() {
console.log("getData");
}
export default setData;

单独引入

1
import getData from "../../util";

如果使用结构赋值方式引入会报错

1
import { getData } from "../../util";//TypeError: Object(...) is not a function
方法三

对象方式导出

1
2
3
4
5
6
7
function setData() {
console.log("setData");
}
function getData() {
console.log("getData");
}
export default { setData, getData };

调用方式引入

1
2
3
4
5
//引入
import util from "../../util";

//调用
util.getData();

导入图片资源

方法一

require 方式导入

1
2
3
4
5
6
7
8
9
10
11
12
import { Component } from 'react'
import { View, Image } from '@tarojs/components'

export default class Index extends Component {
render() {
return (
<View className='index'>
<Image src={require('../../img/1.png')}></Image>
</View>
)
}
}
方法二

import 方式导入

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Component } from 'react'
import { View, Text, Button, Image } from '@tarojs/components'
import img from '../../img/1.png'

export default class Index extends Component {
render() {
return (
<View className='index'>
<Image src={img}></Image>
</View>
)
}
}

导入样式资源

src\pages\test\test.less

1
2
3
4
5
6
7
.index {
.img {
width: 100%;
margin-top: 30px; //小写px会自动转换成rem,大小PX不会转换
}
}

src\pages\test\test.jsx

1
2
3
4
5
6
7
8
9
10
11
12
import { Component } from 'react'
import { View, Text, Button, Image } from '@tarojs/components'
import './test.less'
export default class Index extends Component {
render() {
return (
<View className='index'>
<Image className='img' src={img}></Image>
</View>
)
}
}

条件渲染

三目运算符加上函数调用的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Component } from 'react'
import { View, Text, Button, Image } from '@tarojs/components'

export default class Index extends Component {
state = {
isShow: false,
}
getDom() {
let { isShow } = this.state
return isShow ? (
<Button onClick={this.handleClick}>test!!</Button>
) : (
'isShow:false'
)
}

render() {
return <View className='index'>{this.getDom()}</View>
}
}

列表循环

使用方法

Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 Nerv/小程序 识别哪些元素发生了变化。因此你应当给数组中的每一个元素赋予一个确定的标识。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { Component } from 'react'
import { View, Text, Button, Image } from '@tarojs/components'

export default class Index extends Component {
state = {
isShow: false,
list: [
{ id: 1, title: '张三' },
{ id: 2, title: '李四' },
{ id: 3, title: '王五' },
],
}

render() {
const { list } = this.state
return (
<View className='index'>
{list.map((item, index) => {
return <View key={item.id}>{item.title}</View>
})}
</View>
)
}
}

key 的取值

必须同时满足三个条件:

  1. 稳定
  2. 可预测
  3. 唯一(相对于其他兄弟元素)

最好的 key 就是数组里的 ID(通常由后端生成),他能同时满足以上三个条件,同时也不需要自己去生成。如果没有 ID,你能保证数组的元素某个键值字符串都是不同的(例如 item.title),那么使用那个字符串键值也可以。如果源数据没有提供很好的 key 值,或者需要遍历的数组生成的。那么你最好在数据创建或者修改之后给他添加一个好的 key 值:

与 React 的不同

在 React 中,JSX 是会编译成普通的 JS 的执行,每一个 JSX 元素,其实会通过 createElement 函数创建成一个 JavaScript 对象(React Element),因此实际上你可以这样写代码 React 也是完全能渲染的:

1
2
3
4
5
6
7
const list = this.state.list
.map((l) => {
if (l.selected) {
return <li>{l.text}</li>
}
})
.filter(React.isValidElement)

你甚至可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
const list = this.state.list
.map((l) => {
if (l.selected) {
return {
$$typeof: Symbol(react.element),
props: {
children: l.text,
},
type: 'li',
}
}
})
.filter(React.isValidElement)

但是 Taro 中,JSX 会编译成微信小程序模板字符串,因此你不能把 map 函数生成的模板当做一个数组来处理。当你需要这么做时,应该先处理需要循环的数组,再用处理好的数组来调用 map 函数。例如上例应该写成:

1
2
3
4
5
const list = this.state.list
.filter((l) => l.selected)
.map((l) => {
return <li>{l.text}</li>
})

Children 与组合

src\pages\dialog\testDialog.jsx 父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Component } from 'react'
import { View, Text, Image } from '@tarojs/components'
import Dialog from './dialog'

export default class TestDialog extends Component {
render() {
return (
<View className='index'>
<Dialog>
<Text>我是第一个Dialog组件</Text>
</Dialog>
{/* myTxt="你好!!!" //传递属性 */}
<Dialog myTxt='你好!!!'>
<Image src={require('../../img/1.png')}></Image>
{/*类似插槽 */}
</Dialog>
</View>
)
}
}

src\pages\dialog\dialog.jsx 子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Component } from 'react'
import { View } from '@tarojs/components'

export default class Dialog extends Component {
config = {
navigationBarTitleText: '弹出框',
}
render() {
return (
<View className='index'>
{/* {this.props.myTxt}传递的属性 */}
{/* {this.props.children}类似插槽的功能 */}
{this.props.myTxt}弹出框组件!!!{this.props.children}
</View>
)
}
}

注意事项

请不要对 this.props.children 进行任何操作。Taro 在小程序中实现这个功能使用的是小程序的 slot 功能,也就是说你可以把 this.props.children 理解为 slot 的语法糖,this.props.children 在 Taro 中并不是 React 的 ReactElement 对象,因此形如 this.props.children && this.props.children、this.props.children[0] 在 Taro 中都是非法的。
this.props.children 无法用 defaultProps 设置默认内容。由于小程序的限制,Taro 也无法知道组件的消费者是否传入内容,所以无法应用默认内容。
不能把 this.props.children 分解为变量再使用。由于普通的 props 有一个确切的值,所以当你把它们分解为变量运行时可以处理,this.props.children 则不能这样操作,你必须显性地把 this.props.children 全部都写完整才能实现它的功能。

事件处理

src\pages\event\event.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { Component } from 'react'
import { View, Button } from '@tarojs/components'

export default class Event extends Component {
state = {
name: '张山',
}
//第一个参数是传递的参数,第二个参数是event事件
handleClick(param, event) {
console.log(param, event)
//如果有两个div包裹且都要点击事件类似的情况,这就有事件冒泡
//阻止事件冒泡
event.stopPropagation()
}
render() {
return (
<View className='index'>
{/* .bind第一个参数绑定this指向,第二个参数是传递的参数 */}
<Button onClick={this.handleClick.bind(this, this.state.name)}>
event
</Button>
</View>
)
}
}

.bind 第一个参数绑定 this 指向,第二个参数是传递的参数。
如果遇到事件冒泡需要阻止用event.stopPropagation()

运行环境

内置环境变量

注意:环境变量在代码中的使用方式,参考
Taro 在编译时提供了一些内置的环境变量来帮助用户做一些特殊处理

process.env.TARO_ENV

用于判断当前编译类型,目前有 weapp / swan / alipay / h5 / rn / tt / qq / quickapp 八个取值,可以通过这个变量来书写对应一些不同环境下的代码,在编译时会将不属于当前编译类型的代码去掉,只保留当前编译类型下的代码,例如想在微信小程序和 H5 端分别引用不同资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Component } from 'react'
import { View, Button } from '@tarojs/components'

const isH5 = process.env.TARO_ENV
export default class Event extends Component {
componentWillUnmount() {
if (isH5) {
console.log('现在的环境是web')
// require("path/to/h5/name"); //引入h5的样式或者资源也能加载不同的组件
} else {
console.log('现在的环境是小程序端')
// require("path/to/weapp/name");
}
}
render() {
return <View className='index'></View>
}
}

不同的运行环境可以引入不同的样式或者资源也能加载不同的组件

1
2
3
4
5
if (process.env.TARO_ENV === 'weapp') {
require('path/to/weapp/name')
} else if (process.env.TARO_ENV === 'h5') {
require('path/to/h5/name')
}

同时也可以在 JSX 中使用,决定不同端要加载的组件

1
2
3
4
5
6
7
8
render () {
return (
<View>
{process.env.TARO_ENV === 'weapp' && <ScrollViewWeapp />}
{process.env.TARO_ENV === 'h5' && <ScrollViewH5 />}
</View>
)
}

接口请求

Taro.request(option)

src\pages\blog\blog.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import Taro from '@tarojs/taro'
import { useState } from 'react'
import { View, Text, Button } from '@tarojs/components'

function Blog() {
const [articleList, setArticleList] = useState([])

const testHandler = () => {
Taro.request({
url: 'https://apiblog.jspang.com/default/getArticleList',
}).then((res) => {
console.log(res.data)
setArticleList(res.data.list)
})
}
return (
<View>
<Text>接口请求</Text>
<Button onClick={testHandler}>获取数据</Button>
{articleList.map((item, index) => {
return <View key={index}>- {item.title} </View>
})}
</View>
)
}
export default Blog

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!