仿饿了么H5项目-React+antd-mobile实战(二)-Tabs导航

搭建项目

使用create-react-app创建一个新的react项目。

npx create-react-app my-app
cd my-app
npm start

如需使用typescript作为动态类型检测,则直接使用以下命令创建项目(笔者默认使用typescript):

npx create-react-app my-app --typescript

如果你想在现有项目添加typescript支持,请参考https://react.docschina.org/docs/static-type-checking.html

安装ant-design-mobile:

npm install ant-design-mobile --save

安装react-router-dom:

npm install react-router-dom --save

安装redux、react-redux、redux-thunk:

npm install redux react-redux redux-thunk --save

配置路由

在src文件夹新建layout、pages两个文件夹。layout文件夹下新建MainLayout.tsx文件,pages下新建Home、Order、My三个文件夹,在三个文件夹内分别新建一个index.tsx文件。

|-src
    |-layout
        |-MainLayout.tsx
    |-pages
        |-Home
            |-index.tsx
        |-Order
            |-index.tsx
        |-My
            |-index.tsx

给pages下面的三个文件夹分别添加如下代码:

import React from 'react';

const Home:React.FC = (props: any) => {

    return (
        
点餐
) }; export default Home;
import React from 'react';

const Order:React.FC = (props: any) => {

    return (
        
订单
) }; export default Order;
import React from 'react';

const My:React.FC = (props: any) => {

    return (
        
我的
) }; export default My;

在MainLayout.tsx中添加如下代码:

import React from 'react';

interface IProps {
    history: any;
    location: any;
}

interface IState {
    collapsed: Boolean;
    activeIndex: number;
}

export default class MainLayout extends React.Component {
    render() {
        return (
            
{this.props.children}
); } }

在src新建routes文件夹。在routes文件夹内新建两个文件,分别为index.tsx、children.tsx:

|-src
    |-routes
        |-index.tsx
        |-children.tsx

在children.tsx中添加如下代码:

import React from 'react';
import {Route} from "react-router-dom";
import MainLayout from '../layout/MainLayout';
import Home from '../pages/Home/index';
import Order from '../pages/Order/index';
import My from '../pages/My/index';


export const ChildRouter = (props: any) => (
    
        
        
        
        
        
    
);

在index.tsx中添加如下代码:

import React from 'react';
import {HashRouter, Route, Switch} from "react-router-dom";

import {ChildRouter} from './children';

const BasicRouter = () => (
    
        
            
            
        
    
);

export default BasicRouter;

在App.tsx中,作如下改动:

import React from 'react';
import 'antd/dist/antd.css';
import './App.scss';
import BasicRouter from './route';

function App() {
    return (
        
    );
}

export default App;

至此,一个嵌套路由就配置好了,在浏览器中输入localhost:3000/#/看看会出现什么。

编写Tabs组件

在src下新建components文件夹及Tabs文件夹,Tabs文件夹下再新建index.tsx、index.scss:

|-src
    |-components
        |-index.tsx
        |-index.scss

在index.tsx中编写如下代码:

import React from 'react';
import './index.scss';

interface IProps {
    onTabChange: Function;
    activeIndex: number;
    tabList: any[];
}

const Tabs: React.FC = (props) => {

    return (
        
{ props.tabList.map(item => (
{ props.onTabChange(item.key); }} >
{item.text}
)) }
) }; export default Tabs;

编写样式:

.tabs-wrap {
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  bottom: 0;
  width: 100%;
  height: 50px;
  border-top: 1px solid #e0e0e0;

  .tabs-item {
    flex: 1;
    text-align: center;
    font-size: 12px;
    color: #8a8a8a;

    &.active {
      color: #1296db;

      .tabs-icon.home {
        background: url("../../assets/home1.png") center no-repeat;
        background-size: contain;
      }

      .tabs-icon.order {
        background: url("../../assets/order1.png") center no-repeat;
        background-size: contain;
      }

      .tabs-icon.my {
        background: url("../../assets/my1.png") center no-repeat;
        background-size: contain;
      }
    }

    .tabs-icon {
      display: inline-block;
      width: 25px;
      height: 25px;
      margin-bottom: 4px;
    }

    .tabs-icon.home {
      background: url("../../assets/home.png") center no-repeat;
      background-size: contain;
    }

    .tabs-icon.order {
      background: url("../../assets/order.png") center no-repeat;
      background-size: contain;
    }

    .tabs-icon.my {
      background: url("../../assets/my.png") center no-repeat;
      background-size: contain;
    }
  }
}

图标请到iconfont或GitHub仓库自行下载。
然后修改MainLayout.tsx:

import React from 'react';
import './MainLayout.scss';
import Tabs from '../components/Tabs/index';

interface IProps {
    history: any;
    location: any;
}

interface IState {
    collapsed: Boolean;
    activeIndex: number;
}

export default class MainLayout extends React.Component {
    state: IState = {
        collapsed: false,
        activeIndex: 0,
    };

    tabList: any[] = [
        {
            key: 0,
            text: '点餐',
            icon: 'home',
        },
        {
            key: 1,
            text: '订单',
            icon: 'order',
        },
        {
            key: 2,
            text: '我的',
            icon: 'my',
        },
    ];

    componentDidMount(): void {
        const {location} = this.props;
        let activeIndex = 0;
        switch (location.pathname) {
            case '/':
                activeIndex = 0;
                break;
            case '/index/order':
                activeIndex = 1;
                break;
            case '/index/my':
                activeIndex = 2;
                break;
            default:
                break;
        }
        this.setState({activeIndex});
    }

    toggle = (): void => {
        this.setState({
            collapsed: !this.state.collapsed,
        });
    };

    handleChange = (index: number): void => {
        const {history} = this.props;
        let url = '/';
        switch (index) {
            case 0:
                url = '/';
                break;
            case 1:
                url = '/index/order';
                break;
            case 2:
                url = '/index/my';
                break;
            default:
                break;
        }
        this.setState({
            activeIndex: index,
        });
        history.replace(url);
    };

    render() {
        const {activeIndex} = this.state;
        return (
            
{this.props.children}
); } }

打开浏览器查看效果


图1.png

至此,一个Tabs组件的开发完成。

你可能感兴趣的:(仿饿了么H5项目-React+antd-mobile实战(二)-Tabs导航)