React18学习笔记(四) 路由案例--记账本

一.准备

1.功能演示

在这里插入图片描述

2.创建项目
npx create-react-app my-react-bill-test
3.安装依赖

安装以下依赖:npm i +xxx

1).Redex状态管理工具:@reduxjs/toolkit和react-redux
2).路由:react-router-dom
3).时间处理js库:dayjs
4).类名处理库:classnames
5).移动端组件库:antd-mobile----重点
6).axios
4.配置路径别名

输入@即可指代src路径
要求:

  • 1).webpack中的路径解析配置:把@解析为src
  • 2).在vsCode中,输入@时自动联想出src下的子级目录
对于要求一

下载craco插件

-为什么要下载craco插件?
-CRACO的项目本身把webpack配置包装到了黑盒中无法直接修改,需要借助插件之力

配置步骤:

a.安装craco:npm i -D @craco/craco
b.项目根目录下创建配置文件craco.config.js
c.在配置文件中添加路径解析配置如下:
const path=require('path')
module.exports={
   
   
    //webpack配置
    webpack:{
   
   
        //配置别名
        alias:{
   
   
            //约定:使用@表示src文件所在路径
            '@':path.resolve(__dirname,'src')
        }
    }
}
d.包文件中配置启动和打包命令如下:
"script":{
   
   
    "start":"craco start",
    "build":"craco build"            
}
对于要求二

新增jsconfig.json文件并在其中配置如下:

{
   
   
    "compilerOptions":{
   
   
        "baseUrl":"./",
        "paths":{
   
   
            "@/*":[
                "src/*"
            ]
        }
    }
}
5.使用json-server实现数据Mock

步骤:

    a.安装:npm i -D json-server
    b.准备一个db.json文件
    c.添加启动命令如下:
        "server":"json-server ./server/db.json --port 8888"
    d.访问接口进行测试

优化:合并命令

安装concurrently:
    npm install concurrently --save-dev
配置package.json:
	"start": "concurrently \"npm run server\" \"craco start\"",

*合并结果:npm run start命令同时启动json-server服务器

二.整体路由设计

新增如下文件:

src
├─router               
│  └─index.js
├─pages              
│  ├─Layout       
│  │  └─index.js      
│  ├─Month        
│  │  └─index.js      
│  ├─Year       
│  │  └─index.js  
│  ├─New       
        └─index.js    
1.配置路由文件router/index.js
// 导入子路由
import Layout from "@/pages/Layout"
import New from "@/pages/New"
import Month from "@/pages/Month"
import Year from "@/pages/Year";
// 导入createBrowserRouter,作用是创建路由
import {
   
    createBrowserRouter } from "react-router-dom";
import {
   
    Navigate } from "react-router-dom";
// 创建路由实例对象
const router = createBrowserRouter([
  // 根路径重定向配置
  {
   
   
    path: "/",
    element: <Navigate to="/layout/month" replace />, // 重定向到目标路径
  },
  {
   
   
    path: '/layout',
    element: <Layout />,
    children: [
      {
   
   
        index: true, // 默认子路由
        element: <Month /> // 访问/article时默认显示
      },
      {
   
   
        path: 'year',
        element: <Year />
      },
      {
   
   
        path: 'month',
        element: <Month />
      },
      {
   
   
        path: 'new',
        element: <New />
      }
    ]
  },
])
// 导入路由实例对象
export default router;
2.在入口文件中导入路由实例对象
//src/index.js
import {
   
     RouterProvider } from 'react-router-dom';
import router from './router'
import {
   
   Provider} from 'react-redux'
import store from './store'

root.render(
  <Provider store={
   
   store}>
    <RouterProvider router={
   
   router} />
  </Provider>
);
......

三.功能验证

1.使用antd-mobile定义主题色
  • 新增src/theme.css
:root {
   
   
  /* 基础主题变量 */
  --adm-color-primary: #a062d4;
  --adm-color-success: #00b578;
  
  /* 按钮样式变量 */
  --adm-button-background-color: #a062d4;
  --adm-button-border-radius: 20px;
  
  /* 字体变量 */
  --adm-font-size-main: 16px;
}

/* 局部主题示例 */
.purple-theme {
   
   
  --adm-color-primary: #722ed1;
  --adm-button-background-color: #722ed1;
}
  • 导入
    //src/index.js
    import "@theme.css"
  • 使用
//src/pages/Layout/index.js
<Button type="primary">测试全局</Button> 
<div className="purple-theme"> 
    <Button type="primary">测试局部</Button> 
</div>

结果:按钮有样式

2.使用Redux管理账户列表

思路:

  1. 在RTK中配置state,reducer和异步action

  2. 在组件中dispatch异步action

步骤:

  • step1:新建账单列表相关store
//src/store/modules/billStore.js
import {
   
    createSlice } from '@reduxjs/toolkit'
import axios from 'axios'
const billStore = createSlice({
   
   
  name: 'bill',
  initialState: {
   
   
    // 账单列表
    billList: [],
  },
  reducers: {
   
   
    // 设置账单列表
    setBillList(state, action) {
   
   
      state.billList = action.payload
    }
  }
})
const {
   
    setBillList } = billStore.actions

// 异步获取账单列表
const getBillList = () => {
   
   
  return async (dispatch) => {
   
   
    const res = await axios.get('http://localhost:8888/list')
    dispatch(setBillList(res.data))
  }
}
export {
   
    getBillList }

const reducer = billStore.reducer
export default reducer
  • step2:组合子模块,导出store实例
// src/store/index.js
import billReducer from './modules/billStore.js'
import {
   
    configureStore } from '@reduxjs/toolkit'
const store = configureStore({
   
   
  reducer: {
   
   
    bill: billReducer// 这里的key要和子模块的name一致,即:name: 'bill'
  }
})
export default store
  • step3:在入口文件中注入
//src/index.js
import {
   
   Provider} from 'react-redux'
import store from './store'
......
root.render(
  <Provider store={
   
   store}>
    <RouterProvider router={
   
   router} />
  </Provider>
);
  • step4:组件中使用useEffect触发异步action
//Layout/index.js
  const dispatch = useDispatch()
  useEffect(() => {
   
   
    dispatch(getBillList())
  }, [dispatch])

结果:浏览器>网络,新增一个get请求

3.使用antd-mobile的tabbar组件配置底部标签栏

官网文档:https://mobile.ant.design/zh/components/tab-bar
安装:sass:npm i -D sass
代码:

//新建Lqyout/index.scss
.layout{
   
   
  .container{
   
   
    position:fixed;
    top:0;
    bottom:50px;
  }
  .footer{
   
   
    position:fixed;
    bottom:0;
    width:100%;
  }
}
//Layout/index.js
import {
   
    Outlet, useNavigate } from "react-router-dom";
import {
   
    TabBar } from "antd-mobile";
import {
   
    useEffect } from "react";
import {
   
    useDispatch } from 'react-redux'
import {
   
    getBillList } from "@/store/modules/billStore";
import {
   
    BillOutline, AddCircleOutline, CalculatorOutline } from 'antd-mobile-icons'
import '@/pages/Layout/index.css'
const tabs = [
  {
   
   
    key: 'month',
    title: '月度账单',
    icon: <BillOutline />,
  },
  {
   
   
    key: 'new',
    title: '记账',
    icon: <AddCircleOutline />,
  },
  {
   
   
    key: 'year',
    title: '年度账单',
    icon: <CalculatorOutline />,
  }
]
const Layout = () => {
   
   
  const dispatch = useDispatch()
  useEffect(() => {
   
   
    dispatch(getBillList())
  }, [dispatch])

  const navigate = useNavigate()
  //点击绑定在tabbar的onChange'事件
  const swithRoute = (path) => {
   
   
    navigate(path)
  }
  
  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值