小白入门上手使用多端开发框架 Taro

开发环境搭建

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,react.js)