Fork me on GitHub

taro使用教程(详细版)

Taro框架的简介和开篇介绍

Taro是由京东凹凸实验室推出的框架,目的就是解决多端混乱的局面,也是当下比较新兴的一个框架。
当我们按照一种模式一种代码进行开发,开发完成后,项目就有了在任何终端显示的能力,这是一种想想都很爽的。那具体Taro有那些优点,请看下面的图片。
在这里插入图片描述

目前Taro支持的终端

  • 微信小程序
  • H5 移动端Web页面
  • 百度小程序
  • 支付宝小程序
  • 快应用
  • ReactNative
  • 字节跳动小程序
  • QQ轻应用
    是目前支持小程序最多的前端框架,并且支持ReactNatvie,说明我们可以轻易的生成媲美原生的APP应用。所以公司的应用如果想全网推广,占用最多的流量入口的话,使用Taro就完全没有问题。
    有熟悉uni的同学会讲uni也有这样类似的功能,生成多端应用的功能,而且还有专属的编辑器,调试很方便,下边就放一个taro与uni-app以及其他例如mpvue等的对比图
    在这里插入图片描述
    由此可见,Taro 的强大之处,以及Taro框架在前端的技术的占比会越来越高。而且用统一的框架、统一的API、统一的代码规范以及统一的代码结构,是多么棒的开发体验。
    一次开发就可以完成所有主流平台的布局,人力和时间成本压缩到最低,感觉节省了一个亿哦。

下边我们就一起来揭秘Taro这神奇的面纱把

Taro的环境搭建和Hello World

前置知识

学习这个前端框架,你需要一些前置知识:

  • HTML、CSS,JavaScript这三个是基础知识,最起码要了解能作出简单的静态页面
  • 理解MVVM框架,如果会React框架是最好的
  • 了解ES6相关语法,作为一个当下流行的框架以及2020年的前端开发用ES6让代码规范起来,对项目开发和管理更加的方便

Taro编译工具的介绍

Taro是一套遵循React语法规范的多端开发解决方案,使用Taro,只书写一套代码,再通过Taro的编译工具,讲源代码分别编译出可以再不同端(微信小程序,H5,RN等)运行代码。

所以说这里的Taro编译工具是非常重要的,这里附带一张图。
在这里插入图片描述

Taro开发环境的安装

1.第一步是安装@tarojs/cli(脚手架工具),也有教开发工具的。

这个你可以使用npm或者yarn进行全局安装,命令如下:

npm的安装方式

npm install -g @tarojs/cli

 

yarn的安装方式

yarn global add @tarojs/cli

 

打开命令行后,输入上边的命令。

2.安装完成后,就可以用脚手架创建项目,命令如下:
taro init taro-dome

 

这里有个小坑就是如果你使用npm来安装脚手架的时候,有很大机率会失败,这些失败多是因为国内网络环境限制的。有两种解决方案,第一是"fangqiang"来进行安装,第二种是使用yarn来进行暗转,我这里就使用了yarn。

Hello World程序

通过上边的创建项目,我们的项目已经建立好了,然后就是运行项目,命令如下:

cd taro-dome
npm run dev:h5

 

在这里运行的是h5模式的,如果要运行小程序的根据package.json中的script设置可知相应的运行方式。

在这里插入图片描述
运行后页面会在浏览器显示Hello World,默认的端口为10086,如图:
在这里插入图片描述

Taro生成小程序代码并预览

Taro可以生成多端代码,在上一节只生成了h5的显示,这次我们就先来进行生成小程序代码,并进行预览。

生成微信小程序的代码
npm run dev:weapp

输入完命令后,taro编译器自动为我们生成小程序代码到dist目录中。
编译后dist目录
这里边的app.js、app.json以及app.wxss 这都是微信小程序所对应的文件,有过微信小程序开发的肯定觉得很熟悉,这就是Taro的强大之处,也是Taro框架的开发者肯定是个webpack开发的大牛,编译生成对应的终端的代码,而不是一个壳子嵌套。

在微信开发者工具中预览项目

开发小程序的肯定知道微信开发者工具,如果你是初学的这里给你一个下载的链接,方便下载学习:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
下载后安装步骤很简单,跟安装QQ几乎一样。
安装完成后,你需要注册一个账号,这个自己按照提示注册就可以了。

注册后导入一个小程序项目
在这里插入图片描述
需要注意的是这不是新建,而是导入一个项目。目录选择的是你的taro项目刚才编译后生成的dist目录
AppId如果有在公众平台注册可以填,没有默认是一个测试号直接导入即可。

导入后你就可以看到在微信开发者工具中显示Hello World!了。
在这里插入图片描述

注意坑点

千万不要在微信开发者工具中修改dist目录,因为这个文件是由taro编译而来的;
如果要修改在taro的原项目修改,然后通过编译将修改的内容编译到dist文件中

Taro的目录介绍

在目录介绍前肯定会有疑惑,Taro是多端统一框架,前边我们利用编译工具生成了h5和微信小程序的代码,那么其他的支付宝小程序、百度小程序等又是如何生成?
这些的答案都在项目的package.json文件中的scripts部分当中:

"scripts": {
    "build:weapp": "taro build --type weapp",
    "build:swan": "taro build --type swan",
    "build:alipay": "taro build --type alipay",
    "build:tt": "taro build --type tt",
    "build:h5": "taro build --type h5",
    "build:rn": "taro build --type rn",
    "build:qq": "taro build --type qq",
    "build:quickapp": "taro build --type quickapp",
    "dev:weapp": "npm run build:weapp -- --watch",
    "dev:swan": "npm run build:swan -- --watch",
    "dev:alipay": "npm run build:alipay -- --watch",
    "dev:tt": "npm run build:tt -- --watch",
    "dev:h5": "npm run build:h5 -- --watch",
    "dev:rn": "npm run build:rn -- --watch",
    "dev:qq": "npm run build:qq -- --watch",
    "dev:quickapp": "npm run build:quickapp -- --watch"
  },

 

我们就以dev为例解释下dev: 后边的都是哪一个平台的

  • weapp 微信小程序
  • h5 手机web用于公众号和浏览器等
  • swan 百度小程序
  • alipay 支付宝小程序
  • tt 字节跳动小程序
  • qq QQ小程序
  • jd 京东小程序
  • quickapp 快应用
  • rn React Native
    这些类型执行都和微信小程序的一样,都是将: 后的改成相对应的模式即可
npm run dev:weapp
或
yarn dev:weapp

 

下边就介绍下Taro的项目目录结构

dist目录

这个目录在上边生成微信小程序代码时已经见到了,是我们在预览时自动生成的,每次进行预览都会根据我们预览的终端不同,编译成不同代码。

每次编译时都会删除以前的代码,这个小伙伴么要注意一下。

config目录

这个就是项目的一些配置,这些配置以后会不断深入学习,但是现在还不了解,可以先不进行配置。否则会影响项目的运行。

node_modules

项目所需的依赖包,就是使用npm install进行安装的包,一般不需要修改。

src目录

这个是最重要的,这个是我们的源码目录,开发的所有代码都在这个里边。

下边给一个官方的目录结构说明

├── dist                   编译结果目录
├── config                 配置目录
|   ├── dev.js             开发时配置
|   ├── index.js           默认配置
|   └── prod.js            打包时配置
├── src                    源码目录
|   ├── pages              页面文件目录
|   |   ├── index          index 页面目录
|   |   |   ├── index.js   index 页面逻辑
|   |   |   └── index.css  index 页面样式
|   ├── app.css            项目总通用样式
|   └── app.js             项目入口文件
└── package.json

 

Taro使用Hooks的新特性

React Hooks的优缺点

既然我们要用Hooks来写,我们就要了解React Hooks的优缺点,为什么要用Hooks,那么我们就来看下Hooks的优缺点吧!
这个优缺点是通过和传统的React.Component进行对比得出的。

React Hooks的优点
  1. 更容易复用代码
  2. 清爽的代码风格
  3. 代码量更少
  4. 更容易发现无用的状态和函数
  5. 更容易拆分组件
React Hooks的缺点
  1. 状态不同步
  2. 副作用代码从主动式变成响应式
如何避免React Hooks的常见问题
  1. 不要在useEffect里面写太多的依赖项,划分这些依赖项成多个useEffect,这样更好维护
  2. 如果你碰到状态不同步的问题,可以考虑下手动传递参数到函数。如:
   // showCount的count来自父级作用域 
   const [count,setCount] = useState(xxx); 
   function showCount(){ console.log(count) } 
   
   // showCount的count来自参数 
   const [count,setCount] = useState(xxx); 
   function showCount(c){ console.log(c) }
  1. 一定要加入eslint-plugin-react-hooks这个插件,并且重视它的警告
  2. 使用useRef来保存你的引用并在re-render的时候主动更新ref的对应属性,这样可以避免“引用是旧”的这个烦人的问题,但这种方式hack味道浓郁。

使用Hooks来改写Index组件

在src/pages/index/index.jsx文件:
原文件:

import Taro, { Component } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import './index.less'

export default class Index extends Component {

  componentWillMount () { }

  componentDidMount () { }

  componentWillUnmount () { }

  componentDidShow () { }

  componentDidHide () { }

  config = {
    navigationBarTitleText: '首页'
  }

  render () {
    return (
      <View className='index'>
        <Text>Hello world!</Text>
      </View>
    )
  }
}

修改成hooks方式:
import Taro, { useState } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import './index.less'

function Index(){
  
  const [userName] = useState('Hello Taro!')

  return (
    <View>
      <Text>{userName}</Text>
    </View>
  )
}

export default Index

如果你对React Hooks不熟悉的话,这里有一套免费的Hooks学习视频教程:https://www.jspang.com/detailed?id=59
如果您对React也不太熟悉的话,没关系这边有一整套的React学习视频,学习完后上手项目没有问题的:https://jspang.com/detailed?id=56

Taro中组件传值

使用Taro 的一个好处就是要可以用组件化的方式进行编程,所以编写组件在Taro中是每天都需要作的工作。
下边我们先来创建一个自组件,然后进行组件的传值,Taro的组件传值跟React的一样利用props,因此如果你对React的组件传值比较熟悉的化,这里很容易理解。

在Taro项目中的src/pages/index文件夹下面建立一个Child组件

child.jsx组件

import { View, Text } from '@tarojs/components'
function Child(){
  return ( 
    <View><Text>我是子组件</Text></View>
  )
}

然后在Index组件中引入,这里给出全部代码方便学习
import Taro, { useState } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import './index.less'
import Child from "./child"

function Index(){
  
  const [userName] = useState('Hello Taro!')

  return (
    <View>
      <Text>{userName}</Text>
      <Child></Child>
    </View>
  )
}

export default Index

父组件向子组件传值

在上边说过,Taro的传值跟React的一样,父组件向子组件传值是通过props进行;
在Taro中也是可以这样传值的,现在修改index.jsx代码,把userName传递给子组件。

import Taro, { useState } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import './index.less'
import Child from "./child"

function Index(){
  
  const [userName] = useState('Hello Taro!')

  return (
    <View>
      <Text>{userName}</Text>
      <Child userInfo={userName} ></Child>
    </View>
  )
}

export default Index

传递后,子组件要增加props参数,然后才能用props进行接收。

import { View, Text } from '@tarojs/components'
function Child(props){
  return ( 
    <View>
        <Text>我是子组件</Text>
        <View><Text>接收来自父组件的值:{props.userInfo}</Text></View>
    </View>
  )
}

export default Child

这个组件间的传值非常的简单,当我们会用组件的形式编写页面和组件时,你就可以作一些小东西了。

但现在你可以看到,我们把页面和组件放到了一个文件夹下,并且都使用了jsx扩展名。
那Taro时如何区分那些是组件,那些是页面的?
其实它是通过自身的路由来区分的,只要配置路由的,就是页面,没配置的就默认是组件。
下边我们来看下Taro中的路由吧!

Taro 路由配置和介绍

Taro中的路由和React 的路由不同,它是通过app.jsx中的pages来配置的,并且谁配置在第一个数组位置,谁就是默认打开的首页。
在这里插入图片描述

首先配置路由

新建一个页面

在/src/pages/文件夹下,建立一个/blog文件夹,在文件夹下面建立一个blog.jsx文件,写入下面的代码:

import {View , Text} from '@tarojs/components'
function Blog(){
    return (
        <View>
            <Text>Blog Page</Text>
        </View>
    )
}
export default Blog
路由配置

有了页面之后就可以到/src/app.jsx下,然后在pages的数组里面加入代码。

pages: [
    'pages/blog/blog',
    'pages/index/index'
],

这里需要注意一点,就是你不需要用import引入Blog页面,这个Taro为我们自动做好了。修改完成后,可以到浏览器中看一下,可以看到默认页面已经变成了Blog页面了。

页面间的跳转

页面跳转的方法

Taro提供了6个相关的导航API,我们可以使用这些API进行跳转,需要注意的是这些有些是小程序专用的。

  • navigateTo: 最基本的跳转方式,可以返回上级页面。三端都支持的,小程序、H5、React Native。
  • redirectTo:不记录上集页面,直接跳转。三端都支持的,小程序、H5、* React Native。
  • switchTab: Tab之间进行切换,这个要配合Taro的导航栏一起使用,三端都支持的,小程序、H5、React Native。
  • navigateBack: 返回上一级页面,这个在小程序中常使用,三端都支持的,小程序、H5、React Native。
  • relaunch:关闭所有额面,打开到应用内某个页面。三端都支持的,小程序、H5、React Native。
  • getCurrentPages: 获取当前页面信息所用,这个H5是不支持的。(注意)
页面跳转Demo

做个Demo,我们从Blog页面,跳转到Index页面,我们的程序如何来编写。

为了方便学习这里给出blog.jsx的全部代码:

import Taro from '@tarojs/taro'
import {View , Text ,Button} from '@tarojs/components'
function Blog(){
    const gotoIndex=()=>{
        Taro.navigateTo({url:'/pages/index/index'})
    }
    return (
        <View>
            <Text>Blog Page</Text>
            <Button onClick={gotoIndex}>我要去Index页面</Button>
        </View>
    )
}
export default Blog

这样我们就实现了Taro中路由的跳转。

Taro路由传参

Taro的路由传参利用查询字符串的形式

Taro中进行传参,一般会使用查询字符串的形式,也就是在跳转的url上,加一个?问号的形式,然后后边跟上参数。

现在我们就在Blog.jsx页面用,useState的形式声明一个变量,再通过跳转把值带到Index.jsx页面。

import Taro ,{useState}from '@tarojs/taro'
import {View , Text ,Button} from '@tarojs/components'
function Blog(){

    const  [blogTitle,setBlogTitle]=useState('JSPang Blog')

    const gotoIndex=()=>{
        Taro.navigateTo({url:'/pages/index/index?blogTitle='+blogTitle})
    }
    return (
        <View>
            <Text>Blog Page</Text>
            <Button onClick={gotoIndex}>我要去Index页面</Button>
        </View>
    )
}
export default Blog
接收传递参数并显示在页面上

在参数已经可以传递了,那如何在Index.jsx进行接收那,其实也非常简单。只要使用this.$router.params就可以进行接收。

当然我们要接收参数,可以在useEffect()中进行(useEffect是React Hooks的方法,不了解的同学请去了解下),

useEffect(()=>{
setBlogTitle(this.$router.params.blogTitle)
},[])

为了更好的学习,这给出接收的全部代码,
index.jsx的代码:

import Taro, {  useState ,useEffect} from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import Child from './child.jsx'
import './index.less'

function Index(props){
  const [userName ,setUserName] = useState('Hello World!!!!')
  const [blogTitle,setBlogTitle] = useState('')
  useEffect(()=>{
    setBlogTitle(this.$router.params.blogTitle)
  },[])
  return ( 
    <View>
        <Text>{userName}</Text>
        <Child userName={userName}></Child>
        <View>{blogTitle}</View>
    </View>
  )

}

export default Index
多参数的传递和接收

多个参数和多个参数的接收,传递的时候只要用&进行链接就可以了,比如下面这样。(有前端开发经验的同学,对这个肯定不会陌生)

Taro.navigateTo({url:'/pages/index/index?blogTitle='+blogTitle+'&introduce='+introduce})

为了学习方便,这里给出blog,jsx的全部代码:

import Taro ,{useState}from '@tarojs/taro'
import {View , Text ,Button} from '@tarojs/components'
function Blog(){
introduce
    const  [blogTitle,setBlogTitle]=useState('JSPangBlog')
    const  [introduce,setIntroduce]=useState('111111')

    const gotoIndex=()=>{
        Taro.navigateTo({url:'/pages/index/index?blogTitle='+blogTitle+'&introduce='+introduce})
    }
    return (
        <View>
            <Text>Blog Page</Text>
            <Button onClick={gotoIndex}>我要去Index页面</Button>
        </View>
    )
}
export default Blog

接收参数跟单参数接收方法一样,不作过多介绍,直接给出代码,

index.jsx代码:

import Taro, {  useState ,useEffect} from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import Child from './child.jsx'
import './index.less'

function Index(props){
  const [userName ,setUserName] = useState('Hello World!!!!')
  const [blogTitle,setBlogTitle] = useState('')
  const  [introduce,setIntroduce]=useState('')
  useEffect(()=>{
    setBlogTitle(this.$router.params.blogTitle)
    setIntroduce(this.$router.params.introduce)
  },[])
  return ( 
    <View>
        <Text>{userName}</Text>
        <Child userName={userName}></Child>
        <View>{blogTitle}</View>
        <View>{introduce}</View>
    </View>
  )

}

export default Index
 

JavaScript资源引入的方法

JavaScript的引入和React的引入方式差不多,比如现在我们定义了一个方法叫做XieDaJiao(谢大脚),然后再定义一个方法叫liuying(刘英)。

在/src目录下,新建一个/tools文件夹,然后在文件夹下边建立一个index.js文件,输入下面的代码。

export function xiedajiao(){
    console.log('我是谢大脚')
}

export function liuying(){
    console.log('我是刘英')
}


建立完成后,我们在blog.jsx文件中引入这个,需要用ES的解构的方式引入:
import {xiedajiao,liuying} from '../../tools'

然后使用的方法,也是利用在useEffect中运行,如下:

useEffect(()=>{
    xiedajiao()
    liuying()
},[])

引入图片的方式

Taro引入图片的方式有两种: import xxx from ‘…’ 然后用将xxx放到相应的src的方式和直接在src中用require方式
下方是blog.jsx的代码,是用import的方式:

import Taro ,{useState ,useEffect}from '@tarojs/taro'
import {View , Text ,Button,Image} from '@tarojs/components'
import {xiedajiao,liuying} from '../../tools'
import newbbd  from '../../static/newbbd0001.jpg'

function Blog(){

    useEffect(()=>{
        xiedajiao()
        liuying()
    },[])



    const  [blogTitle,setBlogTitle]=useState('JSPangBlog')
    const  [introduce,setIntroduce]=useState('111111')
    const gotoIndex=()=>{
        Taro.navigateTo({url:'/pages/index/index?blogTitle='+blogTitle+'&introduce='+introduce})
    }
    return (
        <View>
            <Text>Blog Page111</Text>
            <Button onClick={gotoIndex}>我要去Index页面</Button>
            <View>
                <Image src={newbbd} width="100px" height="100px" />
            </View>
        </View>
    )
}
 

如果想用require的方式,将Image组件的src属性改为:

<Image src={require('../../static/newbbd0001.jpg')} width="100px" height="100px" />

 

更多资源的引入方式,可以来看下Taro资源引入的文档:http://taro-docs.jd.com/taro/docs/static-reference.html

 

JSX的列表渲染

在开始介绍远程数据请求前,先对JSX的列表渲染做下介绍,给JSX不熟悉的朋友提供便利。

构建数组对象

先使用JS的基本语法,打开blog.jsx文件然后再blog方法里编写代码:

const girls = [
    {id:1,name:'胡一菲'},
    {id:2,name:'陈美嘉'},
    {id:3,name:'诸葛大力'},
    {id:4,name:'咖喱酱'}
]

在JSX代码中渲染列表

blog.jsx的全部代码

import Taro ,{useState ,useEffect}from '@tarojs/taro'
import {View , Text ,Button,Image} from '@tarojs/components'
import {xiedajiao,liuying} from '../../tools'

function Blog(){

    useEffect(()=>{
        xiedajiao()
        liuying()
    },[])
    ·
	const girls = [
	    {id:1,name:'胡一菲'},
	    {id:2,name:'陈美嘉'},
	    {id:3,name:'诸葛大力'},
	    {id:4,name:'咖喱酱'}
	]
	
    const  [blogTitle,setBlogTitle]=useState('JSPangBlog')
    const  [introduce,setIntroduce]=useState('111111')
    const gotoIndex=()=>{
        Taro.navigateTo({url:'/pages/index/index?blogTitle='+blogTitle+'&introduce='+introduce})
    }
    return (
        <View>
            <Text>Blog Page111</Text>
            <Button onClick={gotoIndex}>我要去Index页面</Button>
            <View>
            { girls.map((item,index)=>{
			    return (
			        <View>{item.name}</View>
			    )
			}) }
			</View>
        </View>
    )
}

在JSX中使用逻辑判断

在JSX中使用逻辑判断,不能像下边这样用判断:

<view>
    {
        if(zhujueNum===1){
            return ('张伟')
        }else{
            return('吕子乔')
        }
    }
</view>

需要使用判断要用三目运算符:

<view>
    男主角是:{zhujueNum==1?'张伟':'吕子乔'}
</view>

或者也可以使用,短路运算符:

<view>
    男主角是:{zhujueNum==1 && '张伟' || '吕子乔'}
</view>

请求远程数据

Taro的远程数据请求,利用Taro的request的方式,这里给出request的参数文档:

```javascript

https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html

```
下边我们在blog.jsx文件中,编写一个testHandler方法,方法中使用Taro.request后去远端数据,这里数据请求的路径url,你可以去mockJs网站,也可以自己用node等方式创建一个数据请求路径,或者你项目开发时候的路径

const getData= ()=>{
    Taro.request({
        url:'...'
    }).then(res=>{
        console.log(res.data)
    })
}

然后在JSX中编写一个按钮,加上onClick事件,代码如下:

<Button onClick={getData}>获取数据</Button>

遍历渲染获取到的数据

先用useState声明一个articleList,代码如下:

const  [articleList,setArticleList] = useState([])

 

然后在return中使用map进行遍历,如下:

{
    articleList.map((item,index)=>{
        return (<View key={index}>- {item.title} </View>)
    })
}

blog.jsx完整的代码:

import Taro, { useState } from '@tarojs/taro'
import { View, Text, Button } from '@tarojs/components'

function Blog2(){
    const [dataList, setDataList] = useState([])

    const getData = () => {
        Taro.request({
            url: 'https://apiblog.jspang.com/default/getArticleList'
        })
        .then((res)=>{
            console.log(res.data)
            setDataList(res.data.list)
        })
    }

    return (
        <View>
            <View><Text>数据请求</Text></View>
            <Button onClick={getData} >获取数据</Button>
            <View>
                {
                    dataList.map((item, index)=>{
                        return (
                            <View key={index} >{item.title}</View>
                        )
                    })
                }
            </View>
        </View>
    )
}
export default Blog2

 


 

文章就分享到这,欢迎关注“前端大神之路” 

posted @ 2020-10-13 14:53  广东靓仔-啊锋  阅读(12321)  评论(0编辑  收藏  举报