开发环境搭建
1、需要安装的软件【点击对应链接下载即可】
Windows / Mac
环境依赖
- nodejs [推荐安装LTS版本]
编码工具/编辑器
小程序端工具
2、开发环境配置
- node 安装成功之后
- 打开【终端】查看下node的版本
- node -v, 出现v xx.xx.x 的相关信息,代表你安装成功了
- 在终端执行如下步骤
# 全局安装taro的命令行工具
npm install @tarojs/cli
# 出现 Taro v x.x.x 证明安装成功
taro
3、简单 Hello World 项目体验
- project 是你生成项目的名字,可以是你想称呼的。例如 example、test、demo等
- 然后一路回车,首次走默认的即可
# taro init 之后,见下图1,init成功之后,见下图2
taro init project
cd project
# 安装依赖,避免init 项目过程中依赖安装不完整的情况
npm install
-[注意]:如果你npm install 出现错误,别慌,按照如下操作走一波。
rm -rf node_modules package-lock.json
npm install
图1:
4、生成项目目录介绍
.
├── babel.config.js # Babel 配置
├── .eslintrc.js # ESLint 配置
├── config # 编译配置目录
│ ├── dev.js # 开发模式配置
│ ├── index.js # 默认配置
│ └── prod.js # 生产模式配置
├── package.json # 项目的核心。它包含名称、描述和版本之类的信息,以及运行、开发以及有选择地将项目发布到 NPM 所需的信息。
├── dist # 打包目录
├── project.config.json # 小程序项目配置
├── src # 源码目录
│ ├── app.config.js # 全局配置
│ ├── app.less # 全局 样式
│ ├── app.js # 入口组件
│ ├── index.html # H5 入口 HTML
│ └── pages # 页面
│ └── index
│ ├── index.config.js # 页面配置
│ ├── index.less # 页面 CSS
│ └── index.jsx # 页面组件,如果是 Vue 项目,此文件为index.vue
.
5、本地开发环境启动
- 注:npm run dev:h5/weapp/tt 等都是本地开发热更新,改代码预览实施生效.
- 打开终端,cd 到你项目工程的目录,分别执行如下命令。
- 使用webstorm 编辑器,可以使用另一种方式启动。如
- 使用vscode 编辑器,点击右侧上方菜单栏目【Terminal】--【New Terminal】-- 就会在当前项目路径下方打开一个终端面板。,输入如下对应命令即可启动对应端的服务。
H5
cd your project
npm run dev:h5
- 见如下图,证明启动服务成功,服务启动成功之后,会自动在浏览器打开该listening网址 http://0.0.0.0:10089
- 效果图如:
weapp 微信小程序
npm run dev:weapp
- 执行完如上命令之后,会把代码转换成小程序端可运行代码在dist目录下
见下图,证明服务启动成功
- 生成的文件目录如:
- 打开下载好的微信开发工具
- 点击小程序--》导入项目---》目录【打开项目所在路径,到dist/即可】---》AppID有就填写你自己真是的值,没有就是默认 --》最后点击导入就会打开。如
- 效果图如:
tt 头条小程序/抖音小程序
npm run dev:tt
- 执行完如上命令之后,会把代码转换成小程序端可运行代码在dist目录下
见下图,证明服务启动成功
- 生成的文件目录如
-
- 打开下载好的字节跳动开发工具
- 点击小程序--》导入---》【打开项目所在目录,到dist/即可】如
- 效果图如:
百度 百度小程序
npm run dev:swan
- 执行完如上命令之后,会把代码转换成小程序端可运行代码在dist目录下
见下图,证明服务启动成功
- 生成的文件目录如
-
- 打开下载好的百度开发工具
- 点击小程序--》加号 ➕ ---》导入项目---》【打开项目所在目录,到dist/即可】--》无AppID,点击测试号
如
- 效果图如:
注意如果你不知道对应端的小程序应该启动什么命令,如下:
npm run dev:tt # 头条
npm run dev:weapp # 微信
npm run dev:swan # 百度
npm run dev:alipy # 支付宝
npm run dev:qq # QQ
npm run dev:jd # 京东
npm run dev:h5 # H5
npm run dev:quickapp # 快应用
初识、写 Taro
一、简单的文本渲染
import React, { Component } from 'react'
import { View, Text } from '@tarojs/components'
export default class Index extends Component {
constructor() {
super();
this.state = {
defaultValue: 'Hello World!!'
};
}
componentWillMount() {}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {}
componentDidHide() {}
render() {
const { defaultValue } = this.state
return (
{/* 文本渲染 */}
{defaultValue}
);
}
}
二、JSX 数组只能使用 Array.map
import React, { Component } from 'react'
import { View, Text } from '@tarojs/components'
const testData = [
{
label: '星期一',
id: 1,
value: 'Monday',
},
{
label: '星期二',
id: 2,
value: 'Tuesday',
},
{
label: '星期三',
id: 3,
value: 'Wednesday',
},
];
export default class Index extends Component {
constructor() {
super();
}
componentWillMount() {}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {}
componentDidHide() {}
render() {
return (
{testData.map((item) => {
return (
{item.label}
{item.value}
);
})}
);
}
}
三、绑定点击事件
import React, { Component } from 'react'
import { View, Text } from '@tarojs/components'
export default class Index extends Component {
constructor() {
super();
this.state = {
defaultValue: 'Hello World!!',
number: 0,
}
}
componentWillMount() {}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {}
componentDidHide() {}
handleClick1 = () => {
this.setState({
defaultValue: "1、2、3、变了!!!",
});
console.log("你现在点击我了");
};
render() {
const { defaultValue, number } = this.state;
return (
{/* 文本渲染 */}
{defaultValue}
{/* 绑定点击事件,写法1 */}
点击我改变defaultValue
{/* 绑定点击事件,写法2,不推荐,根据实际场景,例如error重新请求数据 onClick={()=>this.fetchData()} */}
{
// 操作state自身最好使用如下方式
this.setState((prevState) => {
return {
number: prevState.number + 1,
};
});
}}
style={styles.viewStyle}
>
{number}
);
}
}
const styles = {
viewStyle: {
background: 'pink',
color: '#fff'
},
viewStyleFont: {
fontSize: '14px'
}
}
.home {
padding: 16Px;
&__week {
display: flex;
justify-content: space-between;
font-size: 16Px;
}
&__btn {
width: 163Px;
height: 38Px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, rgba(242,20,12,1) 0%,rgba(242,39,12,1) 70%,rgba(242,77,12,1) 100%);
border-radius: 26Px;
&--txt {
font-size: 14Px;
color: rgba(255,255,255,1);
}
}
}
- state
- 上述操作修改了state,简单说下,不要直接修改state,例如,this.state.defaultValue = '1、2、3',因为此种方式不会重新渲染组件,不走render,如果安装了elsint校验,会过不去的。
- State的更新可能是异步的,立马执行之后,是无法直接获取到最新的 state ,React 其实会维护着一个 state 的更新队列,每次调用 setState 都会先把当前修改的 state 推进这个队列,在最后,React 会对这个队列进行合并处理,然后去执行回调。根据最终的合并结果再去走下面的流程(更新虚拟dom,触发渲染真实dom)
- state使用的三种方式
// 第一种
this.setState({ number: this.state.number + 1 }) // this.state.number 0
// 第二种
this.setState({ number: this.state.number + 1 },() => {
console.log("callback: ", this.state.number); // 2
});
// 第三种
this.setState(prevState => {
console.log("func: " + prevState.number); // 1
return {
number: prevState.number + 1
};
},()=>{
console.log('now '+ this.state.number) // 2
});
四、父子组件通信
- props 传值通信
- 子组件
import React, { Component } from 'react';
import { View, Text } from '@tarojs/components';
export default class Child extends Component {
static defaultProps = {
langName: '',
enName: '',
onNameEvent: () => {},
};
constructor() {
super();
}
componentWillMount() {}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {}
componentDidHide() {}
emitNameEvent = (langName) => {
this.props.onNameEvent(langName);
};
// 界面描述
render() {
const { langName, enName } = this.props;
return (
this.emitNameEvent(langName)}>{langName}
{enName}
);
}
}
const styles = {
container: {
width: '100%',
display: 'flex',
justifyContent: 'space-between',
},
};
- 父组件
import React, { Component } from 'react'
import { View, Text } from '@tarojs/components'
import Child from './components/test';
const testData = [
{
label: '星期一',
id: 1,
value: 'Monday',
},
{
label: '星期二',
id: 2,
value: 'Tuesday',
},
{
label: '星期三',
id: 3,
value: 'Wednesday',
},
];
export default class Index extends Component {
constructor() {
super();
}
componentWillMount() {}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {}
componentDidHide() {}
render() {
return (
{testData.map((item) => {
return (
{
console.log('拿到子组件的name',name)
}}
/>
);
})}
);
}
}
四、生命周期介绍
- 组件的生命周期,指的是一个 React 组件从挂载,更新,销毁过程中会执行的生命钩子函数。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentWillMount() {}
componentDidMount() {}
componentWillUpdate(nextProps, nextState) {}
componentWillReceiveProps(nextProps) {}
componentDidUpdate(prevProps, prevState) {}
shouldComponentUpdate(nextProps, nextState) {}
componentWillUnmount() {}
render() {
return (
Hello, world!
现在的时间是 {this.state.date.toLocaleTimeString()}.
);
}
}
上述组件中生命周期一一简单叙述
初始化阶段
- constructor,顾名思义,组件的构造函数。一般会在这里进行 state 的初始化,事件的绑定等
挂载阶段
- componentWillMount, 组件挂载到dom之前调用。是当组件在进行挂载操作前,执行的函数,一般紧跟着 constructor 函数后执行
- componentDidMount,是当组件挂载在 dom 节点后执行。全程只执行一次,一般会在这里执行一些异步数据的拉取等动作
更新阶段
- shouldComponentUpdate,比较当前组件的this.props/this.state和传入的nextProps/nextState,是否需要重渲染的判断,未改变返回false,当前组件更新停止。若组件的state与props发生改变则返回true,当前组件的更新开始。可以减少组件不必要的渲染,优化组件性能。渲染优化。
- componentWillReceiveProps,传入的参数(nextProps)为父组件传递给子组件的新props,通过本作用域中的this.state与传过来的nextProps进行比较来得出是否要重新调用render进行渲染,可以有效减少无效渲染次数,并提高周期的开发效率。你可以在这里根据新的 props 来执行一些相关的操作,例如某些功能初始化等
- componentWillUpdate,当组件在进行render更新之前的预渲染函数。[基本不用]
- componentDidUpdate,当组件完成更新时,会执行的函数,传入两个参数是 prevProps 、prevState,为组件更新前的props和state,需要重点注意的是,更新阶段内不许使用setState方法进行state值的修改,否则会引起render的循环重渲染。[基本不用]
卸载阶段
- componentWillUnmount,当组件准备销毁时执行。在这里一般可以执行一些回收的工作,例如 - clearInterval(this.timer) 这种对定时器的回收操作,清除componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。
五、绑定样式
- 方式一:行内
{/* 例如文本渲染,设置文字颜色 */}
{defaultValue}
- 方式二、行内绑定变量
{/* 绑定点击事件,写法2 */}
{number}
const styles = {
viewStyle: {
background: 'pink',
color: '#fff',
},
viewStyleFont: {
fontSize: '14px',
},
};
- 方式三、绑定class样式类名
- 样式命名,遵循BEM规范
{/* 手写按钮 */}
点击我改变Hello World
.home {
padding: 16Px;
&__btn {
width: 163Px;
height: 38Px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, rgba(242,20,12,1) 0%,rgba(242,39,12,1) 70%,rgba(242,77,12,1) 100%);
border-radius: 26Px;
&--txt {
font-size: 14Px;
color: rgba(255,255,255,1);
}
}
}
入门
- 渐进式入门教程【这篇教程适合对喜欢边学边做或小程序开发完全没有了解的开发者】
深入学习
[React、Vue两大框架根据实际使用技术栈学习]
进阶
结语
- taro 官方文档
- 如果你觉得我上述安装即使啰嗦,可直接看官方文档安装及使用篇
- 优秀学习资源汇总
- 如果有什么疑问,可以直接留言呀