Taro

P01:Taro 框架简介和介绍

Taro是京东凹凸实验室推出的框架,目的就是解决多端混乱的局面。当我们按照一种模式一种代码进行开发,开发完成后,项目就有了在任何终端显示的能力,这让人想想都很爽。

1. Taro 的优点

  1. 多端运行:编译多端,通过自身的编译工具,编译成不同环境下的代码,实现多端运行。
  2. React:React 语法规范,可以让我们使用 JSX 和 React 相关的语法(包括 Hooks)来开发小程序应用。
  3. 组件化:组件化开发,组件化开发是前端的一个标准,但是小程序自身的组件化有很多不足,不过直接使用 Taro 正弥补了这些不足。
  4. TS 语法:TypeScript,现在 TypeScript 很流行,尤其是在大型项目中,Taro 也是完全支持 TS 语法。
  5. 开发体验:开发体验好,效率高。
  6. 自动化:开发流程自动化,在开发中可以把精力放到程序业务本身上来,因为 Taro 提供了全套的开发流程自动化配置,让我们更专心解决业务逻辑。

2. 目前 Taro 支持的终端

  1. 微信小程序
  2. H5 移动端 Web 页面
  3. 百度小程序
  4. 支付宝小程序
  5. 快应用
  6. ReactNative
  7. 字节跳动小程序
  8. QQ 轻应用

P02:Taro 开发环境的搭建和Hello World

1. Taro 开发环境的安装

首先 Taro 项目是基于 node 的,所以需要我们的电脑上首先有 node 环境。

之后,安装 Taro 脚手架工具。

npm 安装 CLI

npm install -g @tarojs/cli

yarn 安装 CLI

yarn global add @tarojs/cli

cnpm 安装 CLI

cnpm install -g @tarojs/cli

注意:如果安装过程出现sass相关的安装错误,请在安装 mirror-config-china 后重试。

npm install -g mirror-config-china

安装过后我们可以查看一下我们的 Taro 的版本:

taro -v

可以使用 npm info 查看 Taro 版本信息,在这里你可以看到当前最新版本:

npm info @tarojs/cli

2. 初始化项目

安装过后就是初始化项目:

taro init myApp

npm 5.2+ 也可在不全局安装的情况下使用 npx 创建模板项目:

npx @tarojs/cli init myApp

之后要进入项目根目录:

cd myApp

3. 编译运行

微信小程序编译命令

# yarn
$ yarn dev:weapp
$ yarn build:weapp

# npm script
$ npm run dev:weapp
$ npm run build:weapp

# 仅限全局安装
$ taro build --type weapp --watch
$ taro build --type weapp

# npx 用户也可以使用
$ npx taro build --type weapp --watch
$ npx taro build --type weapp

# watch 同时开启压缩
$ set NODE_ENV=production && taro build --type weapp --watch # CMD
$ NODE_ENV=production taro build --type weapp --watch # Bash

H5 编译命令

# yarn
$ yarn dev:h5
$ yarn build:h5

# npm script
$ npm run dev:h5
$ npm run build:h5

# 仅限全局安装
$ taro build --type h5 --watch
$ taro build --type h5

# npx 用户也可以使用
$ npx taro build --type h5 --watch
$ npx taro build --type h5

P03:Taro 生成小程序代码并预览

1. 生成小程序代码

cd mydemo1
yarn dev:weapp  //关键代码

输入完命令后,taro编译器自动为我们生成小程序代码到dist目录中。

2. 在微信开发者工具中预览

首先要下载 微信开发者工具 下面是下载地址:

微信开发者工具下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

之后就可以导入我们已经创建好的项目,目录输入到 dist 目录。

避坑:

就是我们千万不要在微信开发者工具中修改dist目录中的代码,而是要持续开发Taro代码。因为我们既然用了Taro,目的就是想维护一套代码,而在不同的终端中都可以使用。

如果我们直接维护dist中的代码就使用使用Taro的意义了。

P04:Taro 目录介绍

dist 目录

这个目录是我们在预览的时候自动生成的,每次根据我们进行不同的编译会生成不同的 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

P05:Taro 中子组件的编写和传值

编写子组件

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

编写子组件之后,在父组件中引用一下

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

export default function Index(){

  const [userName ,setUserName] = useState('Hello World!!!!')

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

}

父组件向子组件传值

React 中是通过 props 由父组件向子组件传递值。在 Taro 中也是一样的。

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

export default function Index(){

  const [userName ,setUserName] = useState('Hello World!!!!')

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

}

在子组件中我们是跟 React 中一样,要添加 props 参数,才能使用 props 进行接受父组件的参数。

import { View, Text } from '@tarojs/components'
export default function Child(props){
  return ( 
  <View><Text>我是子组件,父组件向我传值为:{props.userName}</Text></View>
  )
}

P07:Taro 路由配置

Taro 中的路由和 React 中路由是不一样的,它是通过 app.jsx 或者 app.config.jsx 中 的 pages 来配置的,并且谁匹配在第一个数组位置,谁就是默认打开的首页。

新建一个页面

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

配置路由

我们可以找到 /src/app.config.jsx 。然后在 pages 的数组中加入 blog 的路由。

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 ,我们从 Blog 页面 跳转到 Index 页面。

实现跳转需要 使用 Taro 组件,所以我们先引入。并且我们引入了一个 Button 组件。

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

之后我们自己写一个跳转方法。

const gotoIndex=()=>{
    Taro.navigateTo({url:'/pages/index/index'})
}

之后,我们使用 Button 组件,写一个 按钮,并给这个 按钮添加一个点击事件,onClick 事件触发 gotoIndex 方法。

<Button onClick={gotoIndex}>我要去Index页面</Button>

完整代码:

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

P08:Taro 页面间传递参数

通过查询字符串的形式进行传参

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

import Taro ,{useState}from '@tarojs/taro'
import {View , Text ,Button} from '@tarojs/components'
export default 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>
    )
}

接受传递参数并显示在页面上

import { useState, useEffect } from 'react'
import { View, Text } from '@tarojs/components'
import { getCurrentInstance } from '@tarojs/taro';
import Child from './child.jsx';
import './index.css'


export default function Index() {
  const [userName, setUserName] = useState('way-abc');
  const [blogTitle, setBlogTitle] = useState('');
  useEffect(() => { 
    setBlogTitle(getCurrentInstance().router.params.blogTitle); 
   },[])
  return (
    <View>
      <Text>{userName}</Text>
      <Child name={userName}></Child>
      <View>blogTitle: { blogTitle }</View>
    </View>
  )
}

多参数的传递和接受

Taro.navigateTo({url:'/pages/index/index?blogTitle='+blogTitle+'&introduce='+introduce})
import { useState, useEffect } from 'react'
import { View, Text } from '@tarojs/components'
import { getCurrentInstance } from '@tarojs/taro';
import Child from './child.jsx';
import './index.css'


export default function Index() {
  const [userName, setUserName] = useState('way-abc');
  const [blogTitle, setBlogTitle] = useState('');
  const [introduce, setIntroduce] = useState('');
  useEffect(() => { 
    setBlogTitle(getCurrentInstance().router.params.blogTitle); 
    setIntroduce(getCurrentInstance().router.params.introduce)
   },[])
  return (
    <View>
      <Text>{userName}</Text>
      <Child name={userName}></Child>
      <View>blogTitle: { blogTitle }</View>
      <View>{ introduce }</View>
    </View>
  )
}

P09:Taro 静态资源引入方式

这里我们以引入一个 js 文件和 image 文件为例。

JavaScript 资源的引入方法

比如我们在 src 目录下新建一个 tools 目录。然后在文件下面创建一个 index.js 文件。

export function father() {
  console.log("我是father");
}

export function mother() {
  console.log("我是mother");
}

如果我们想在之前写的 blog.jsx 下使用这两个方法,下面是错误演示。

import tools from `../../tools`

正确的是下面的方式:

import {father, mother} from '../../tools'

使用方法如下:

useEffect(()=>{
    father()
    mother()
},[])

图片的引入方式

我们通常会像下面的方式进行引入,但是这样是错误的。

<Image src="../../static/2003351.jpg" style={{ width:"100px", height:"100px"}} />

因为编译之后,我们的目录结构就改变了。跟在本地书写代码时候的路径有所改变,我们可以有两种方法解决这个问题。

import Taro from '@tarojs/taro';
import { useState,useEffect } from 'react';
import { View, Text, Button, Image} from "@tarojs/components"
import { father, mother } from "../../tools"
import img from "../../static/2003351.jpg"


export default function Blog() {
    useEffect(() => { 
        father();
        mother();
    },[])
    const [blogTitle, setBlogTitle] = useState('WayBlog');
    const gotoIndex = () => {
        Taro.navigateTo({url: '/pages/index/index?blogTitle=' + blogTitle})
    }
    return (
        <View>
            <Text>Blog Page</Text>
            <Button onClick={gotoIndex}>我要去 Index 页面</Button>
            <View><Image src={img} style={{ width:"100px", height:"100px"}} /></View>
            <View><Image src={require("../../static/2003351.jpg")} style={{ width:"100px", height:"100px"}} /></View>
        </View>
    )
}

可以使用 import 直接把图片的路径引入进来。之后在设置 src 的时候,用花括号包裹前面引入进来的变量。

或者可以使用 require 来包裹图片路径就可以了。

P10:Taro 中 JSX 的列表渲染

跟 react 中很像,就是使用 map 来循环列表,进行渲染。

import Taro from '@tarojs/taro';
import { useState,useEffect } from 'react';
import { View, Text, Button, Image} from "@tarojs/components"
import { father, mother } from "../../tools"
import img from "../../static/2003351.jpg"


export default function Blog() {
    
    const family = [
        { id: 1, name: 'father' },
        { id: 2, name: 'mother' },
        { id: 3, name: 'son' },
        { id: 4, name: 'daughter'}
    ]

    const [blogTitle, setBlogTitle] = useState('WayBlog');
    const zhujunum = 1;
    const gotoIndex = () => {
        Taro.navigateTo({url: '/pages/index/index?blogTitle=' + blogTitle})
    }
    return (
        <View>
            <Text>Blog Page</Text>
            <Button onClick={gotoIndex}>我要去 Index 页面</Button>
            <View><Image src={img} style={{ width:"100px", height:"100px"}} /></View>
            <View><Image src={require("../../static/2003351.jpg")} style={{ width:"100px", height:"100px"}} /></View>

            {
                family.map((item, index) => {
                    return (
                        <View key={index}>{ item.id }:{item.name}</View>
                    )
                })
            }
            <View>男主角是:{zhujunum === 1 ? 'xyz' : "abc"}</View>
            <View>男主角是:{ zhujunum ===1 && 'xyz' || "abc" }</View>
        </View>
    )
    
}

P11:Taro 请求远程数据

使用 Taro.request 获取远程数据。

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

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

<Button onClick={testHandler}>我要去Index页面</Button>

这时候点击按钮时就应该可以在控制台输出接口返回的数据。

遍历数据进行渲染

这次我们在得到数据后遍历到JSX中,先用useState声明一个articleList,代码如下:

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

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

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

这时候就可以到服务器看一下结果了。当点击按钮后,就会去接口请求首页数据,然后得到数据后渲染到页面上。