Taro与React的本质区别:
React中:一切皆组件
Taro中:小程序端区分页面与组件。配上页面路由的是页面,页面中被引用的自定义组件是组件
一、安装及使用:
参照官方文档 https://nervjs.github.io/taro/docs/GETTING-STARTED.html
视频学习 https://www.imooc.com/learn/1084
安装:
npm install -g @tarojs/cli
使用:
- 初始化系项目
taro init myApp
项目构建配置:
-
Taro可以在多个环境下dev项目
-
项目结构:
- package.json 是依赖包
- package.config.json 是给微信小程序单独提供的
- config 是项目启动编译的配置文件的目录
- dist 是编译好的目录
- src 是原代码
src目录下:
1). index.html是为h5准备的
2). app.js 即是小程序的入口,又是为h5做路由编译的路由文件(react本身是不需要配置路由的,但是需要在app.js里面配置页面地址)
3). 在pages/index/index.js下编写纯h5标签也可以生效。但是在小程序中不适用。如果只做h5端可以把taro当成react用。如果适配多端,必须按照taro规范写代码
- 更改视图:Taro的数据更新,一定是异步的
写法1:数据直接写成一个对象
写法2:数据写在componentDidMount中用this.setState({})设置
import Taro, { Component } from '@tarojs/taro'
import { View, Text, Button } from '@tarojs/components'
import './index.less'
export default class Index extends Component {
config = {
navigationBarTitleText: '首页'
}
// 更改视图:数据写法1
state = {
name: 'Lida'
}
componentWillMount () { }
componentDidMount () {
// 更改视图:数据写法2
// this.setState({name: 'Lida'})
}
componentWillUnmount () { }
componentDidShow () { }
componentDidHide () { }
click () {
this.setState({name: 'Nazi'});
}
render () {
return (
<View className='index'>
<Text>Hello world!</Text>
<Text class="name">{this.state.name}</Text>
<Button onClick={this.click}>Change_name</Button>
</View>
)
}
}
同步更新数据写法:
更新数据之后,执行回调
- props 由父组件传给子组件的属性:
props是只读属性,想要修改必须在父组件通过事件修改
1). 首先定义子组件
import Taro, { Component } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
// 定义class,继承Component
class Child extends Component {
// render函数是必须实现的
render () {
return (
<View>
<Text>{this.props.name}</Text>
</View>
)
}
}
// 给子组件一个默认值
Child.defaultProps = {
name: ''
}
export default Child;
2). 在父组件中引入
import Child from './child'
<Child name="Child-Grey"></Child>
给子组件<Child></Child>传一个name属性
3). 修改props
子组件:
import Taro, { Component } from '@tarojs/taro'
import { View, Text, Button } from '@tarojs/components'
// import './index.less'
// 定义class,继承Component
class Child extends Component {
clickHandler () {
this.props.onchange();
}
// render函数是必须实现的
render () {
return (
<View>
<Text>{this.props.name}</Text>
<Button onClick={this.clickHandler}>调用上层事件</Button>
</View>
)
}
}
// 给子组件一个默认值
Child.defaultProps = {
name: ''
}
export default Child;
父组件:
change () {
this.setState({name: '改变name值,起个中文名'})
}
<Child name={this.state.name} onchange={this.change.bind(this)}></Child>
- Taro提供的UI框架——Taro UI
cnpm install taro-ui@1.5.0 -D
最新版本有bug,组件不能正常使用,文档未说明。
npm安装这个框架会停滞
官方文档 https://taro-ui.aotu.io/#/docs/introduction
注意事项:
- PX要大写,如果不大写会被转换成rem
二、其他(个人学习用)
值得记忆:
- 解构 赋值写法
let {activity: [firstItem]} = this.state;
- Class类的概念
Activity
class Activity extends Component {
constructor () {
// super() 作为函数调用。继承父函数以后必须要执行super(),super的this指向子函数Activity
super(...arguments);
this.state = {
activity: [
{
type: "cut",
info: [
{total: 48, cut: 10},
{total: 58, cut: 20},
{total: 100, cut: 30}
]
}
]
}
}
render () {
// 相当于取this.state中的activity中的数组中的第一个元素,命名为firstItem
let {activity: [firstItem]} = this.state;
return (
<View className="activity">
<Text className="type">{this.getTextByType(firstItem.type)}</Text>
<Text>{this.getLine(firstItem.info)}</Text>
<Text className="length">{this.state.activity.length}个活动</Text>
</View>
)
}
}
- react中写法:
// cata.js
import Taro, { Component } from '@tarojs/taro'
import { View, Text, Image } from '@tarojs/components'
import './cata.less'
class Cata extends Component {
constructor () {
super(...arguments);
this.state = {
selectCata: null, // 选中的分类
cata: [
{id: 1, name: '专场'},
{id: 2, name: '热销'},
{id: 3, name: '折扣'},
{id: 4, name: '汉堡'},
{id: 5, name: '炸鸡'},
{id: 6, name: '饮品'}
]
}
}
handlerClick (item) {
if (this.state.selectCata && this.state.selectCata.id != item.id) {
this.setState({ selectCata: item });
console.log(this.state);
} else if (!this.state.selectCata) {
this.setState({ selectCata: item });
}
}
render () {
let {cata, selectCata} = this.state;
return (
<View className="cata">
{/*
1. .map()循环<Text></Text>
2. 把每一项的id传给key -> key={item.id}
3. 绑定class -> 如果selectCata存在 同时 selectCata.id == item.id,就添加class="select"
4. 对每一项添加点击事件 -> 将每一项的item传给回调函数
5. 回调函数内部逻辑:如果selectCata存在 同时 selectCata.id != item.id,就将当前项的item 传给 selectCata; 如果selectCata不存在就直接赋值。
*/}
{
cata.map((item, index) => {
return <Text onclick={this.handlerClick.bind(this, item)} className={"cata-name " + ((selectCata && selectCata.id == item.id) ? 'select' : null)} key={item.id}>{item.name}</Text>
})
}
</View>
)
}
}
export default Cata;
-
兄弟组件间数据传递解决方案:
1). 通过上级(父)的View组件
2). 通过事件监听,在组件1定义事件,在组件2监听事件执行事件函数
3). Redux