React笔记(七)Antd

一、登录功能

  • 首先要使用antd,要先下载

yarn add antd
  • 登录页面关键代码

import React from 'react'
/*
  1、如果要在react中完成样式隔离,需要如下操作
  1)命名一个xx.module.scss    webpack要求
  2) 在需要的组件中通过ES6方式进行导入,导入的格式如下
  import 模块名 from 'xx.module.scss的路径'
  3) 在页面的标签中引用,引用的格式<标签名 className={模块名.类样式名称}/>或者className={模块名['类样式名称']}/>
*/
/*
  2.antd中Form组件的使用
  2.1 触发Form中的onFinish事件的回调函数它的的条件
  1)必须让
                  
              
           
       
   
) }

二、后台页面设计

import React,{useState,useEffect} from 'react'
import homeStyle from '../assets/css/home.module.scss'
import {Layout,Menu} from 'antd'
import {WindowsOutlined,TrademarkCircleOutlined,UserOutlined} from '@ant-design/icons'
import {useNavigate,Outlet} from 'react-router-dom'
​
const {Header,Sider,Content,Footer}=Layout
​
​
export default function Home() {
  const [menuList,setMenuList]=useState([])
  const nav=useNavigate()
  useEffect(()=>{
    const list=[
      {
        key:'sub1',
        label:'日常业务',
        icon:,
        children:[
          {
            label:'学员管理',
            key:'/home/students'
          },
          {
            label:'班级管理',
            key:'/home/classes'
          }
        ]
      },
      {
        key:'sub2',
        label:'校区管理',
        icon:,
        children:[
          {
            label:'班主任管理',
            key:'/home/directors'
          },
          {
            label:'专业管理',
            key:'/home/subjects'
          }
        ]
      },
      {
        key:'sub3',
        label:'系统管理',
        icon:,
        children:[
          {
            key:'/home/users',
            label:'用户管理'
          }
        ]
      }
    ]
    setMenuList(list)
  },[])
  const go=(item)=>{
    nav(item.key)
  }
  return (
    <>
      
          
           
蜗牛BOSS管理系统
         
                                                                                        {/* 设置子路由出口 */}                                                    
Ant Design ©2023 Created by Ant UED
     
    ) }

三、用户列表

import React, { useState, useEffect } from 'react'
import { Card, Table, Avatar, Button, Space, Popconfirm } from 'antd';
import api from '../api'
export default function Users() {
    const [list, setList] = useState([])
    const columns = [
        {
            title: '用户名',
            dataIndex: 'username'
        },
        {
            title: '邮箱',
            dataIndex: 'email'
        },
        {
            title: '手机',
            dataIndex: 'phone'
        },
        {
            title: '角色',
            dataIndex: 'auth',
            render: (item) => {
                return item == 1 ? '超级管理员' : item == 2 ? '普通管理员' : '暂无'
            }
        },
        {
            title: '头像',
            dataIndex: 'image',
            render: (item) => {
                return 
            }
        },
        {
            title: '操作',
            key: 'action',
            render: (arg1) => {
                return (
                    
                        
                        {deleteUser(arg1._id)}}
                            okText="确认"
                            cancelText="取消">
                            
                        
                    
                )
            }
        }
​
    ]
    useEffect(() => {
        getUsers()
    }, [])
    const getUsers = async () => {
        const result = await api.users.getUsers()
        setList(result.data.result)
    }
​
    const deleteUser = (_id) => {
        console.log('_id', _id);
    }
    return (
        
                           
           
       
  ) }

四、动态菜单

  • 在api/modules/users下编写获取权限菜单的接口

import request from '../../utils/request'
export default{
    getAuthMenus:()=>request.get('/menus/getAuthMenus')
}
  • 在SysMenus.jsx中调用getAuthMenus接口来完成权限菜单数据的获取

 useEffect(()=>{
    getAuthMenus()
  },[])
  const getAuthMenus=async()=>{
    const result=await api.users.getAuthMenus()
    console.log(result.data);
    const rlist=transformDataToMenus(result.data)
    console.log('转换后的结果',rlist);
    setMenuList(rlist)
  }
  • 将后台的权限菜单数据转成antd格式的菜单数据

/**
   * 将后台的权限菜单数据转成antd格式的菜单数据
   */
  const transformDataToMenus=(list)=>{
    return list.map(item=>{
        let menuItem={label:item.title,key:item.path,icon:React.createElement(icons[item.icon])}
        if(item.children){
            menuItem.children=transformDataToMenus(item.children)
        }
        return menuItem
    })
  }
  • 渲染导航列表


 

五、路由鉴权

  • 在components文件夹下创建函数Auth组件

  • 在router/index.js的路由配置中使用包裹起来

  • 关键代码如下

import React,{useEffect} from 'react'
import {Navigate,useNavigate} from 'react-router-dom'
import api from '../api'
import {message} from 'antd'
export default function Auth({children}) {
  //从localStorage获取token
  //如何将结果转成boolean类型
  const nav=useNavigate()
  const isAuth=!!localStorage.getItem('token')
  useEffect(()=>{
    getUserInfo()
  },[])
  const getUserInfo=async()=>{
     try {
        await api.users.getUserInfo()
     } catch (error) {
        message.warning('您的token已失效,请重新登录')
        nav('/login')
     }
  }
  if(isAuth){
    return (
        <>
        {children}
        
      )
  }else{
    message.warning('您还没有登录请登录')
    return (<>
        
    )
  }
}

注意:需要在request.js的响应拦截器中完成Promise.reject()

axios.interceptors.response.use(response=>{
    return response.data
},error=>{
    return Promise.reject(error)
})

六、分页操作

import React, { useState, useEffect } from 'react'
import { Card, Table, Avatar, Button, Space, Popconfirm,Pagination } from 'antd';
import api from '../../api'
export default function Users() {
    const [list, setList] = useState([])
    const [total,setTotal]=useState(0)
    const [pageSize,setPageSize]=useState(10)
    const [current,setCurrent]=useState(1)
    const columns = [
        {
            title: '用户名',
            dataIndex: 'username'
        },
        {
            title: '邮箱',
            dataIndex: 'email'
        },
        {
            title: '手机',
            dataIndex: 'phone'
        },
        {
            title: '角色',
            dataIndex: 'auth',
            render: (item) => {
                return item == 1 ? '超级管理员' : item == 2 ? '普通管理员' : '暂无'
            }
        },
        {
            title: '头像',
            dataIndex: 'image',
            render: (item) => {
                return 
            }
        },
        {
            title: '操作',
            key: 'action',
            render: (arg1) => {
                return (
                    
                        
                        {deleteUser(arg1._id)}}
                            okText="确认"
                            cancelText="取消">
                            
                        
                    
                )
            }
        }
    ]
    useEffect(() => {
        getUsers()
    }, [])
    const getUsers = async (params={pageSize:10,currentPage:1}) => {
        const result = await api.users.getUsers(params)
        setList(result.data.result)
        setTotal(result.data.total)
    }

    const deleteUser = (_id) => {
        console.log('_id', _id);
    }

    const onChange=(page,pageSize)=>{
        let params={pageSize,currentPage:page}
        getUsers(params)
        setCurrent(page)
        setPageSize(pageSize)
    }

    const onSizeChange=(current,pageSize)=>{
        console.log('pageSize',pageSize);
        console.log('current',current);
        let params={pageSize,currentPage:current}
        getUsers(params)
    }
    return (
        
) }

七、面包屑

import React,{useMemo,useEffect,useState} from 'react'
import { Breadcrumb } from 'antd';
import {useLocation} from 'react-router-dom'
import api from '../api'
export default function MyBreadcrumb() {
 const location=useLocation()
 let pathname=location.pathname
 const [breadcrumbAry,setBreadcrumbAry]=useState([])
 useEffect(()=>{
   getAuthMenu()
 },[])
 const getAuthMenu=async()=>{
   const result=await api.users.getAuthMenus()
   transformAry(result.data)
 }
 const transformAry=(list)=>{
  let breadcrumbData={}
  list.forEach(item=>{
      if(item.children){
         item.children.forEach(subItem=>{
          breadcrumbData[subItem.path]=[item,subItem]
         })
      }
   })
  setBreadcrumbAry(breadcrumbData[pathname])
 }
  return (
    <>
        
            {
                !breadcrumbAry?[].map((item,index)=>{item.title}):breadcrumbAry.map((item,index)=>{item.title})
            }
        
    
  )
}

八、增加操作

import React,{useEffect,useState} from 'react'
import MyBreadcrumb from '../../components/MyBreadcrumb';
import {Button,Card,Modal,Form, Input, Select,Upload,Radio} from 'antd'
import { PlusOutlined,LoadingOutlined  } from '@ant-design/icons';
import api from '../../api'


export default function StudentList() {
  const [addForm]=Form.useForm()

  const [classesOptions,setClassesOptions]=useState([])
  const [subjectsOptions,setSubjectsOptions]=useState([])
  const [loading, setLoading] = useState(false);
  const [imageUrl, setImageUrl] = useState();
  useEffect(()=>{
      getAllSubjects()
  },[])
  
  const getAllSubjects=async()=>{
      const result=await api.subjects.getSubjects()
      setSubjectsOptions(result.data.result)
  }
  const changeSubject=async(arg)=>{
      const result=await api.classes.getClassesBySubjectsId(arg)
      setClassesOptions(result.data.result)
  }
  const handleChange = (info) => {
      if (info.file.status === 'uploading') {
          setLoading(true);
          return;
      }
      if (info.file.status === 'done') {
          setLoading(false);
          setImageUrl(`http://www.zhaijizhe.cn:3005/${info.file.response.data[0]}`)
      }
  }
  const uploadButton = (
      
{loading ? : }
上传头像
); const [isModalOpen, setIsModalOpen] = useState(false); const showModal = () => { setIsModalOpen(true); }; const handleOk = () => { setIsModalOpen(false); const params={ name:addForm.getFieldValue(['name']), age:addForm.getFieldValue(['age']), gender:addForm.getFieldValue(['gender'])?addForm.getFieldValue(['gender']):"男", subjectsId:addForm.getFieldValue(['subjectsId']), classesId:addForm.getFieldValue(['classesId']), } if(addForm.getFieldValue(['imagePath']).file.response){ params.imageUrl=`http://www.zhaijizhe.cn:3005${addForm.getFieldValue(['imagePath']).file.response.data[0]}` } console.log('params',params); }; const handleCancel = () => { setIsModalOpen(false); }; return (
{imageUrl ? ( avatar ) : ( uploadButton )}
) }

你可能感兴趣的:(react.js,笔记,前端)