react后台管理系统(三)
🌈个人主页:前端青山
🔥系列专栏:React篇
🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来React篇专栏内容:react后台管理系统(三)
前言
本文档将通过一系列实际案例,详细介绍如何使用 React 和 Ant Design 组件库来构建一个完整的管理员管理页面。我们将涵盖从环境配置、API 调用到表单处理和数据渲染的各个方面,帮助开发者快速掌握相关技能
目录
前言
13.axios的封装
14.添加轮播图
15.渲染轮播图的数据
16.渲染商品列表数据
17.价格/销量/库存排序
18.分类的筛选
19.推荐/秒杀
20.首页数据展示
21.显示中文文案 - i18n - 国际化
22.筛选商品
23.管理员列表
24.添加管理员 - 抽屉
25.管理员编辑
总结
13.axios的封装
axios中文文档|axios中文网 | axios
cnpm i axios -S
Utils/request.js
import axios from 'axios'
// 判断用户当前运行的环境 开发环境 生产环境
// 访问不同的环境 ,请求不同的地址
// 开发环境 npm run start ---- development
// 生产环境 npm run build ---- production
// process.env.NODE_ENV
const isDev = process.env.NODE_ENV === 'development'
// http://121.89.205.189/admin/banner/add
// 请求是请求 /banner/add
const request = axios.create({ // 自定义axios
// baseURL: 'http://121.89.205.189/admin'
// baseURL: isDev ? 'http://localhost:3000/admin' : 'http://182.44.11.110/admin'
baseURL: isDev ? http://182.44.11.110//admin' : 'http://182.44.11.110/admin'
})
// axios 拦截器
// 请求拦截器
// 响应拦截器
export default request
// api/banner.js 封装数据请求
import request from '../utils/request'
// 添加轮播图
export function add (params) {
return request.post('/banner/add', params)
}
// 删除轮播图数据
export function deleteItem (params) {
return request.get('/banner/delete', { params })
}
// 删除所有的轮播图
export function removeAll (params) {
return request.get('/banner/removeAll', { params })
}
// 查询轮播图的数据
export function getBannerList (params) {
return request.get('/banner/list', { params })
}
14.添加轮播图
构建添加轮播图页面
import React from 'react'
import { Input, Space, Button, Image } from 'antd';
const width = { width: '300px'}
function Index() {
return (
<Space direction="vertical">
{/* 点击图片链接 */}
<Input placeholder="link" style={ width }/>
{/* 图片alt属性 */}
<Input placeholder="alt" style={ width }/>
{/* 用来存放图片的base64地址 */}
<Input style={ width }/>
{/* 原始的上传控件,太丑 */}
<Input type="file" hidden></Input>
{/* 点击时相当于要去点击 type="file" */}
<Button>点击选择上传文件</Button>
{/* 预览效果 */}
<Image
height={300}
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
/>
<Button type="primary">提交</Button>
</Space>
)
}
export default Index
获取各自的参数
import React, { useRef, useState } from 'react'
import { Input, Space, Button, Image } from 'antd';
const width = { width: '300px'}
function Index() {
// 使用了 hooks
const [link, setLink] = useState('')
const [alt, setAlt] = useState('')
const [img, setImg] = useState('')
const fileRef = useRef()
// 点击打开选择文件窗口
const selectBanner = () => {
console.log(fileRef.current.input)
// DOM document.getElementById().click()
fileRef.current.input.click()
}
// 获取用户选择的文件信息
const getBanenrInfo = (e) => {
// 获取文件信息
const file = fileRef.current.input.files[0]
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function () {
// 这里的this不是函数值组件中的this
setImg(this.result)
}
}
// 改变 link
const changeLink = (e) => {
console.log(e.target)
setLink(e.target.value)
}
// 改变 alt
const changeAlt = (e) => {
console.log(e.target)
setAlt(e.target.value)
}
// 提交信息
const submitBanner = () => {
const params = { img, link, alt }
console.log(params)
}
return (
<Space direction="vertical">
{/* 受控组件 value 配合 onChange */}
<Input placeholder="link" style={ width } value = { link } onChange = { changeLink }/>
{/* 受控组件 value 配合 onChange */}
<Input placeholder="alt" style={ width } value = { alt } onChange = { changeAlt }/>
<Input style={ width } hidden value = { img }/>
{/* 非受控组件 ref 配合 onChange */}
<Input type="file" hidden ref = { fileRef } onChange = { getBanenrInfo }></Input>
<Button onClick = { selectBanner }>点击选择上传文件</Button>
{/* 如果没有上传图,默认图片
实际上,没有图不可以上传 */}
<Image
height={300}
src={
img === '' ? 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' : img
}
/>
{/* 有图片才可以上传 */}
<Button type="primary" disabled = { img === '' } onClick = { submitBanner }>提交</Button>
</Space>
)
}
export default Index
上传数据到服务器
import React, { useRef, useState } from 'react'
import { Input, Space, Button, Image } from 'antd';
import { useHistory } from 'react-router-dom'
// 引入添加轮播图接口
import { add } from './../../api/banner'
const width = { width: '300px'}
function Index() {
const [link, setLink] = useState('')
const [alt, setAlt] = useState('')
const [img, setImg] = useState('')
// 编程式导航
const history = useHistory()
const fileRef = useRef()
const selectBanner = () => {
console.log(fileRef.current.input)
fileRef.current.input.click()
}
const getBanenrInfo = (e) => {
const file = fileRef.current.input.files[0]
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function () {
setImg(this.result)
}
}
const changeLink = (e) => {
console.log(e.target)
setLink(e.target.value)
}
const changeAlt = (e) => {
console.log(e.target)
setAlt(e.target.value)
}
const submitBanner = () => {
const params = { img, link, alt }
console.log(params)
// 调用接口
add(params).then(res => {
history.push('/banner/list')
})
}
return (
<Space direction="vertical">
<Input placeholder="link" style={ width } value = { link } onChange = { changeLink }/>
<Input placeholder="alt" style={ width } value = { alt } onChange = { changeAlt }/>
<Input style={ width } hidden value = { img }/>
<Input type="file" hidden ref = { fileRef } onChange = { getBanenrInfo }></Input>
<Button onClick = { selectBanner }>点击选择上传文件</Button>
<Image
height={300}
src={
img === '' ? 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' : img
}
/>
<Button type="primary" disabled = { img === '' } onClick = { submitBanner }>提交</Button>
</Space>
)
}
export default Index
15.渲染轮播图的数据
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button } from 'antd'
import { getBannerList } from '../../api/banner'
function Index() {
const [bannerList, setBannerList] = useState([])
useEffect(() => {
getBannerList().then(res => {
setBannerList(res.data.data)
})
}, [])
// 设置表格
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '图片',
dataIndex: 'img',
// text 相当于上面的 img 字段
// record 相当于每一条数据的对象
// index 索引值
render: (text, record, index) => {
return (
<Image src = { text } width = { 200 } height = { 100 } />
)
}
},
{
title: '链接',
dataIndex: 'link'
},
{
title: '提示',
dataIndex: 'alt'
},
{
title: '操作',
render: (text, record, index) => {
return (
<Space>
<Button type="danger">删除</Button>
</Space>
)
}
}
]
return (
<div>
<Table
rowKey = { record => record.bannerid }
dataSource = { bannerList }
columns = { columns } />
</div>
)
}
export default Index
删除轮播图单条数据
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button, Popconfirm } from 'antd'
import { getBannerList, deleteItem, removeAll } from '../../api/banner'
function Index() {
const [bannerList, setBannerList] = useState([])
useEffect(() => {
getBannerList().then(res => {
setBannerList(res.data.data)
})
}, [])
const deleteBannerItem = (bannerid) => {
deleteItem({ bannerid }).then(res => {
// 删除之后重新请求数据
getBannerList().then(res => {
setBannerList(res.data.data)
})
})
}
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '图片',
dataIndex: 'img',
// text 相当于上面的 img 字段
// record 相当于每一条数据的对象
// index 索引值
render: (text, record, index) => {
return (
<Image src = { text } width = { 200 } height = { 100 } />
)
}
},
{
title: '链接',
dataIndex: 'link'
},
{
title: '提示',
dataIndex: 'alt'
},
{
title: '操作',
render: (text, record, index) => {
return (
<Space>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
deleteBannerItem(record.bannerid)
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
}
}
]
const removeAllBanner = () => { // 删除全部的数据
removeAll().then(res => {
// 删除全部数据,只需要再把列表置为空
setBannerList([])
})
}
return (
<div>
<Button onClick = { removeAllBanner }>全部删除</Button>
<Table
rowKey = { record => record.bannerid }
dataSource = { bannerList }
columns = { columns } />
</div>
)
}
export default Index
16.渲染商品列表数据
// api/pro.js
import request from '../utils/request'
export function getProList (params) {
return request.get('/pro/list', { params })
}
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button, Popconfirm, Tooltip,Switch } from 'antd'
import { getProList } from '../../api/pro'
function Index() {
const [ proList, setProList ] = useState([])
useEffect(() => {
// 该项目共有150,测试Table组件的自动分页,写了 200
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
}, [])
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category' },
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice' },
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales' },
{ title: '库存', width: 100, dataIndex: 'stock' },
{ title: '上架状态', width: 110, fixed: 'right', dataIndex: 'issale', render: (text) => <Switch checked = { text }/> },
{ title: '是否推荐', width: 110, fixed: 'right', dataIndex: 'isrecommend', render: (text) => <Switch checked = { text }/> },
{ title: '是否秒杀', width: 100, fixed: 'right', dataIndex: 'isseckill', render: (text) => <Switch checked = { text }/> },
{ title: '操作', width: 180, fixed: 'right', render: (text, record, index) => {
return (
<Space>
<Tooltip title="功能正在开发中">
<Button type="dashed" >编辑</Button>
</Tooltip>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
} },
]
return (
<div>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500 }}
></Table>
</div>
)
}
export default Index
17.价格/销量/库存排序
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button, Popconfirm, Tooltip,Switch } from 'antd'
import { getProList } from '../../api/pro'
function Index() {
const [ proList, setProList ] = useState([])
useEffect(() => {
// 该项目共有150,测试Table组件的自动分页,写了 200
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
}, [])
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category' },
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice',
sorter: (a, b) => a.originprice - b.originprice, // 按照价格排序
},
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales',
sorter: (a, b) => a.sales - b.sales,// 按照销量排序
},
{ title: '库存', width: 100, dataIndex: 'stock',
sorter: (a, b) => a.stock - b.stock, // 按照库存排序
},
{ title: '上架状态', width: 110, fixed: 'right', dataIndex: 'issale', render: (text) => <Switch checked = { text }/> },
{ title: '是否推荐', width: 110, fixed: 'right', dataIndex: 'isrecommend', render: (text) => <Switch checked = { text }/> },
{ title: '是否秒杀', width: 100, fixed: 'right', dataIndex: 'isseckill', render: (text) => <Switch checked = { text }/> },
{ title: '操作', width: 180, fixed: 'right', render: (text, record, index) => {
return (
<Space>
<Tooltip title="功能正在开发中">
<Button type="dashed" >编辑</Button>
</Tooltip>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
} },
]
return (
<div>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500, y: 740 }}
></Table>
</div>
)
}
export default Index
18.分类的筛选
// api/pro.js
import request from '../utils/request'
export function getProList (params) {
return request.get('/pro/list', { params })
}
export function getCategory (params) {
return request.get('/pro/getCategory', { params })
}
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button, Popconfirm, Tooltip,Switch } from 'antd'
import { getProList, getCategory } from '../../api/pro'
function Index() {
const [ proList, setProList ] = useState([])
const [ categoryList, setCategoryList ] = useState([])
useEffect(() => {
// 该项目共有150,测试Table组件的自动分页,写了 200
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
getCategory().then(res => { // 获取分类的数据
const arr = []
res.data.data.forEach(item => { // 处理分类数据
arr.push({ text: item, value: item })
})
setCategoryList(arr)
})
}, [])
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category',
filters: categoryList, // 分类过滤数组
onFilter: (value, record) => record.category.indexOf(value) !== -1 // 返回匹配项
},
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice',
sorter: (a, b) => a.originprice - b.originprice,
},
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales',
sorter: (a, b) => a.sales - b.sales,
},
{ title: '库存', width: 100, dataIndex: 'stock',
sorter: (a, b) => a.stock - b.stock,
},
{ title: '上架状态', width: 110, fixed: 'right', dataIndex: 'issale', render: (text) => <Switch checked = { text }/> },
{ title: '是否推荐', width: 110, fixed: 'right', dataIndex: 'isrecommend', render: (text) => <Switch checked = { text }/> },
{ title: '是否秒杀', width: 100, fixed: 'right', dataIndex: 'isseckill', render: (text) => <Switch checked = { text }/> },
{ title: '操作', width: 180, fixed: 'right', render: (text, record, index) => {
return (
<Space>
<Tooltip title="功能正在开发中">
<Button type="dashed" >编辑</Button>
</Tooltip>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
} },
]
return (
<div>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500, y: 740 }}
></Table>
</div>
)
}
export default Index
19.推荐/秒杀
// api/pro.js
import request from '../utils/request'
export function getProList (params) {
return request.get('/pro/list', { params })
}
export function getCategory (params) {
return request.get('/pro/getCategory', { params })
}
export function updateFlag (params) {
return request.post('/pro/updateFlag', params)
}
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button, Popconfirm, Tooltip,Switch } from 'antd'
import { getProList, getCategory, updateFlag } from '../../api/pro'
function Index() {
const [ proList, setProList ] = useState([])
const [ categoryList, setCategoryList ] = useState([])
useEffect(() => {
// 该项目共有150,测试Table组件的自动分页,写了 200
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
getCategory().then(res => {
const arr = []
res.data.data.forEach(item => {
arr.push({ text: item, value: item })
})
setCategoryList(arr)
})
}, [])
// 修改推荐状态
const changeRecommendFlag = (proid, text) => {
updateFlag({ proid, type: 'isrecommend', flag: text === 1 ? false : true })
.then(() => {
// 重新获取数据
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
})
}
// 修改秒杀状态
const changeSeckillFlag = (proid, text) => {
// text 拿到的上一次的状态,如果上一次的值为1, 代表用户点击完后要变为0
updateFlag({ proid, type: 'isseckill', flag: text === 1 ? false : true })
.then(() => {
// 重新获取数据
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
})
}
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category',
filters: categoryList,
onFilter: (value, record) => record.category.indexOf(value) !== -1
},
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice',
sorter: (a, b) => a.originprice - b.originprice,
},
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales',
sorter: (a, b) => a.sales - b.sales,
},
{ title: '库存', width: 100, dataIndex: 'stock',
sorter: (a, b) => a.stock - b.stock,
},
{ title: '上架状态', width: 110, fixed: 'right', dataIndex: 'issale', render: (text) => <Switch checked = { text }/> },
{ title: '是否推荐', width: 110, fixed: 'right', dataIndex: 'isrecommend',
render: (text,record) => <Switch checked = { text } onChange = { () => { // 改变推荐状态
changeRecommendFlag(record.proid, text)
}}/> },
{ title: '是否秒杀', width: 100, fixed: 'right', dataIndex: 'isseckill',
render: (text,record) => <Switch checked = { text } onChange = { () => { // 改变秒杀状态
changeSeckillFlag(record.proid, text)
}}/> },
{ title: '操作', width: 180, fixed: 'right', render: (text, record, index) => {
return (
<Space>
<Tooltip title="功能正在开发中">
<Button type="dashed" >编辑</Button>
</Tooltip>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
} },
]
return (
<div>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500, y: 740 }}
></Table>
</div>
)
}
export default Index
20.首页数据展示
推荐
复制商品列表的代码至 推荐页面
import request from '../utils/request'
export function getProList (params) {
return request.get('/pro/list', { params })
}
export function getCategory (params) {
return request.get('/pro/getCategory', { params })
}
export function updateFlag (params) {
return request.post('/pro/updateFlag', params)
}
export function showdata (params) {
return request.post('/pro/showdata', params)
}
import React, { useState, useEffect } from 'react'
import { Table, Image, Switch } from 'antd'
import { showdata, updateFlag } from '../../api/pro'
function Index() {
const [ proList, setProList ] = useState([])
useEffect(() => {
// 请求的是 被推荐的数据
showdata({ type: 'isrecommend', flag: 1 }).then(res => {
setProList(res.data.data)
})
}, [])
const changeRecommendFlag = (proid, text) => {
updateFlag({ proid, type: 'isrecommend', flag: text === 1 ? false : true })
.then(() => {
// 重新请求数据
showdata({ type: 'isrecommend', flag: 1 }).then(res => {
setProList(res.data.data)
})
})
}
// 删除了排序以及筛选,只保留 推荐列表的状态
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category' },
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice' },
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales' },
{ title: '库存', width: 100, dataIndex: 'stock' },
{ title: '是否推荐', width: 110, fixed: 'right', dataIndex: 'isrecommend',
render: (text,record) => <Switch checked = { text } onChange = { () => {
changeRecommendFlag(record.proid, text)
}}/> },
]
return (
<div>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500, y: 740 }}
></Table>
</div>
)
}
export default Index
秒杀
import React, { useState, useEffect } from 'react'
import { Table, Image, Switch } from 'antd'
import { showdata, updateFlag } from '../../api/pro'
function Index() {
const [ proList, setProList ] = useState([])
useEffect(() => {
showdata({ type: 'isseckill', flag: 1 }).then(res => {
setProList(res.data.data)
})
}, [])
const changeSeckillFlag = (proid, text) => {
updateFlag({ proid, type: 'isseckill', flag: text === 1 ? false : true })
.then(() => {
showdata({ type: 'isseckill', flag: 1 }).then(res => {
setProList(res.data.data)
})
})
}
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category' },
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice' },
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales' },
{ title: '库存', width: 100, dataIndex: 'stock' },
{ title: '是否秒杀', width: 100, fixed: 'right', dataIndex: 'isseckill',
render: (text,record) => <Switch checked = { text } onChange = { () => {
changeSeckillFlag(record.proid, text)
}}/> },
]
return (
<div>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500, y: 740 }}
></Table>
</div>
)
}
export default Index
21.显示中文文案 - i18n - 国际化
语言包 - 国际化
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App.jsx';
import { ConfigProvider } from 'antd';
// 由于 antd 组件的默认文案是英文,所以需要修改为中文
import zhCN from 'antd/lib/locale/zh_CN';
ReactDOM.render(
<ConfigProvider locale = { zhCN }>
<App />
</ConfigProvider>,
document.getElementById('root')
);
22.筛选商品
import request from '../utils/request'
export function getProList (params) {
return request.get('/pro/list', { params })
}
export function getCategory (params) {
return request.get('/pro/getCategory', { params })
}
export function updateFlag (params) {
return request.post('/pro/updateFlag', params)
}
export function showdata (params) {
return request.post('/pro/showdata', params)
}
export function searchPro (params) {
return request.post('/pro/searchPro', params)
}
import React, { useState, useEffect } from 'react'
import { Table, Image, Space, Button, Popconfirm, Tooltip,Switch, Select, Input } from 'antd'
import { getProList, getCategory, updateFlag, searchPro } from '../../api/pro'
const { Option } = Select
function Index() {
const [ proList, setProList ] = useState([])
const [ categoryList, setCategoryList ] = useState([])
// 设置需要的字段的参数两个 category / search
const [ category, setCategory ] = useState('')
const [ search, setSearch ] = useState('')
useEffect(() => {
// 该项目共有150,测试Table组件的自动分页,写了 200
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
getCategory().then(res => {
// 无需重置分类数据
setCategoryList(res.data.data)
})
}, [])
const changeRecommendFlag = (proid, text) => {
updateFlag({ proid, type: 'isrecommend', flag: text === 1 ? false : true })
.then(() => {
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
})
}
const changeSeckillFlag = (proid, text) => {
updateFlag({ proid, type: 'isseckill', flag: text === 1 ? false : true })
.then(() => {
getProList({ limitNum: 200 }).then(res => {
setProList(res.data.data)
})
})
}
const columns = [
{ title: '序号', width: 100, fixed: 'left', render: (text, record, index) => <span>{index + 1}</span>},
{ title: '名称', width: 260, fixed: 'left', dataIndex: 'proname' },
{ title: '分类', width: 100, dataIndex: 'category' },
{ title: '品牌', width: 100, dataIndex: 'brand' },
{ title: '图片', width: 200, dataIndex: 'img1', render: (text) => <Image src={text} width={80} height={80}/> },
{ title: '原价', width: 100, dataIndex: 'originprice' },
{ title: '折扣', width: 100, dataIndex: 'discount' },
{ title: '销量', width: 100, dataIndex: 'sales' },
{ title: '库存', width: 100, dataIndex: 'stock' },
{ title: '上架状态', width: 110, fixed: 'right', dataIndex: 'issale', render: (text) => <Switch checked = { text }/> },
{ title: '是否推荐', width: 110, fixed: 'right', dataIndex: 'isrecommend',
render: (text,record) => <Switch checked = { text } onChange = { () => {
changeRecommendFlag(record.proid, text)
}}/> },
{ title: '是否秒杀', width: 100, fixed: 'right', dataIndex: 'isseckill',
render: (text,record) => <Switch checked = { text } onChange = { () => {
changeSeckillFlag(record.proid, text)
}}/> },
{ title: '操作', width: 180, fixed: 'right', render: (text, record, index) => {
return (
<Space>
<Tooltip title="功能正在开发中">
<Button type="dashed" >编辑</Button>
</Tooltip>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
} },
]
// 改变分类
const changeCategory = (value) => {
setCategory(value)
}
// 改变关键词的数据
const changeSearch = (e) => {
setSearch(e.target.value)
}
// 搜索
const searchFn = () => {
searchPro({
category, search
}).then(res => {
setProList(res.data.data)
})
}
return (
<div>
<Select style={{ width: 120 }} value={ category } onChange = { changeCategory }>
<Option value="">全部</Option>
{
categoryList && categoryList.map(item => {
return <Option key = { item } value = { item }>
{ item }
</Option>
})
}
</Select>
<Input style={{width:200}} placeholder = '请输入关键词' value={ search } onChange = { changeSearch }></Input>
<Button type="primary" onClick = { searchFn }>搜索</Button>
<Table
columns = { columns }
dataSource = { proList }
rowKey = { record => record.proid }
scroll={{ x: 1500, y: 740 }}
></Table>
</div>
)
}
export default Index
23.管理员列表
// api/users.js
import request from './../utils/request'
export function getAdminList (params) {
return request.get('/admin/list', { params })
}
import React, { useState, useEffect } from 'react'
import { Table, Tooltip, Space, Button, Popconfirm } from 'antd'
import { getAdminList } from '../../api/users'
function Index() {
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (
<>
{
index === 0 ? null : <Space>
<Tooltip title="功能正在开发中">
<Button type="dashed" >编辑</Button>
</Tooltip>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
}
</>
)
}
}
]
return (
<div>
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
</div>
)
}
export default Index
24.添加管理员 - 抽屉
搭建页面的架构
import React, { useState, useEffect } from 'react'
import { Table, Drawer, Space, Button, Popconfirm } from 'antd'
import { getAdminList } from '../../api/users'
function Index() {
// 1.管理员列表
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (
<>
{
index === 0 ? null : <Space>
<Button type="dashed" >编辑</Button>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
}
</>
)
}
}
]
// 2.添加管理员
const [visible, setVisible] = useState(false)
const showDrawer = () => {
setVisible(true)
}
return (
<div>
{/* 2.添加管理员 */}
<Button type="primary" onClick = { showDrawer }>添加管理员</Button>
<Drawer
width={ 500 }
title="添加管理员"
placement="right"
closable={true}
onClose={ () => { setVisible(false) }}
visible={visible}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
{/* 1.管理员列表 */}
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
</div>
)
}
export default Index
添加表单
import React, { useState, useEffect } from 'react'
import { Table, Drawer, Space, Button, Popconfirm, Input, Select, Tree } from 'antd'
import { getAdminList } from '../../api/users'
import menus from './../../router/menus'
function Index() {
// 1.管理员列表
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (
<>
{
index === 0 ? null : <Space>
<Button type="dashed" >编辑</Button>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
}
</>
)
}
}
]
// 2.添加管理员 - 控制抽屉的显示
const [visible, setVisible] = useState(false)
const showDrawer = () => {
setVisible(true)
}
// 2.添加管理员 - 需要的组件状态
const [adminname, setAdminname] = useState('')
const [password, setPasssword] = useState('')
const [role, setRole] = useState('1')
const [checkedKeys, setCheckedKeys] = useState([]) // 用来记录哪些被选中
const changeRole = (value) => {
setRole(value)
}
const onCheck = (checkedKeys) => {
console.log(checkedKeys)
setCheckedKeys(checkedKeys)
}
const addAdminFn = () => {
const obj = { adminname, password, role, checkedKeys }
console.log(obj)
}
// const expandedKeys = ['0-2']
const expandedKeys = []
menus.forEach(item => {
expandedKeys.push(item.key)
})
return (
<div>
{/* 2.添加管理员 */}
<Button type="primary" onClick = { showDrawer }>添加管理员</Button>
<Drawer
width={ 500 }
title="添加管理员"
placement="right"
closable={true}
onClose={ () => { setVisible(false) }}
visible={visible}
>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { adminname } onChange = { (e) => {
setAdminname(e.target.value)
}} />
<Input type="password" placeholder = "请输入密码" value = { password } onChange = { (e) => {
setPasssword(e.target.value)
}} />
<Select value={ role } onChange = { changeRole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onCheck}
checkedKeys={checkedKeys}
treeData={menus}
/>
<Button type="primary" onClick = { addAdminFn }>添加</Button>
</Space>
</Drawer>
{/* 1.管理员列表 */}
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
</div>
)
}
export default Index
提交数据
import request from './../utils/request'
export function getAdminList (params) {
return request.get('/admin/list', { params })
}
export function addAdmin (params) {
return request.post('/admin/add', params)
}
import React, { useState, useEffect } from 'react'
import { Table, Drawer, Space, Button, Popconfirm, Input, Select, Tree } from 'antd'
import { getAdminList, addAdmin } from '../../api/users'
import menus from './../../router/menus'
function Index() {
// 1.管理员列表
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (
<>
{
index === 0 ? null : <Space>
<Button type="dashed" >编辑</Button>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
}
</>
)
}
}
]
// 2.添加管理员 - 控制抽屉的显示
const [visible, setVisible] = useState(false)
const showDrawer = () => {
setVisible(true)
}
// 2.添加管理员 - 需要的组件状态
const [adminname, setAdminname] = useState('')
const [password, setPasssword] = useState('')
const [role, setRole] = useState('1')
const [checkedKeys, setCheckedKeys] = useState([]) // 用来记录哪些被选中
const changeRole = (value) => {
setRole(value)
}
const onCheck = (checkedKeys) => {
console.log(checkedKeys)
setCheckedKeys(checkedKeys)
}
const addAdminFn = () => {
const obj = { adminname, password, role, checkedKeys }
console.log(obj)
addAdmin(obj).then(() => { // 提交表单信息 ************************
// 抽屉消失,表单回归初始状态
setVisible(false)
setAdminname('')
setPasssword('')
setRole('1')
setCheckedKeys([])
// 重新渲染一次页面
getAdminList().then(res => {
setAdminList(res.data.data)
})
})
}
// const expandedKeys = ['0-2']
const expandedKeys = []
menus.forEach(item => {
expandedKeys.push(item.key)
})
return (
<div>
{/* 2.添加管理员 */}
<Button type="primary" onClick = { showDrawer }>添加管理员</Button>
<Drawer
width={ 500 }
title="添加管理员"
placement="right"
closable={true}
onClose={ () => { setVisible(false) }}
visible={visible}
>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { adminname } onChange = { (e) => {
setAdminname(e.target.value)
}} />
<Input type="password" placeholder = "请输入密码" value = { password } onChange = { (e) => {
setPasssword(e.target.value)
}} />
<Select value={ role } onChange = { changeRole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onCheck}
checkedKeys={checkedKeys}
treeData={menus}
/>
<Button type="primary" onClick = { addAdminFn }>添加</Button>
</Space>
</Drawer>
{/* 1.管理员列表 */}
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
</div>
)
}
export default Index
25.管理员编辑
主界面
import React, { useState, useEffect } from 'react'
import { Table, Drawer, Space, Button, Popconfirm, Input, Select, Tree, Modal } from 'antd'
import { getAdminList, addAdmin } from '../../api/users'
import menus from './../../router/menus'
function Index() {
// 1.管理员列表
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (
<>
{
index === 0 ? null : <Space>
{/* 3.编辑管理员数据 */}
<Button type="dashed" onClick = { () => {
setIsModalVisible(true)
}}>编辑</Button>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
}
</>
)
}
}
]
// 2.添加管理员 - 控制抽屉的显示
const [visible, setVisible] = useState(false)
const showDrawer = () => {
setVisible(true)
}
// 2.添加管理员 - 需要的组件状态
const [adminname, setAdminname] = useState('')
const [password, setPasssword] = useState('')
const [role, setRole] = useState('1')
const [checkedKeys, setCheckedKeys] = useState([]) // 用来记录哪些被选中
const changeRole = (value) => {
setRole(value)
}
const onCheck = (checkedKeys) => {
console.log(checkedKeys)
setCheckedKeys(checkedKeys)
}
const addAdminFn = () => {
const obj = { adminname, password, role, checkedKeys }
console.log(obj)
addAdmin(obj).then(() => {
// 抽屉消失,表单回归初始状态
setVisible(false)
setAdminname('')
setPasssword('')
setRole('1')
setCheckedKeys([])
// 重新渲染一次页面
getAdminList().then(res => {
setAdminList(res.data.data)
})
})
}
// const expandedKeys = ['0-2']
const expandedKeys = []
menus.forEach(item => {
expandedKeys.push(item.key)
})
// 3.编辑管理员数据 - 控制对话框的展示
const [isModalVisible, setIsModalVisible] = useState(false);
return (
<div>
{/* 2.添加管理员 */}
<Button type="primary" onClick = { showDrawer }>添加管理员</Button>
<Drawer
width={ 500 }
title="添加管理员"
placement="right"
closable={true}
onClose={ () => { setVisible(false) }}
visible={visible}
>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { adminname } onChange = { (e) => {
setAdminname(e.target.value)
}} />
<Input type="password" placeholder = "请输入密码" value = { password } onChange = { (e) => {
setPasssword(e.target.value)
}} />
<Select value={ role } onChange = { changeRole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onCheck}
checkedKeys={checkedKeys}
treeData={menus}
/>
<Button type="primary" onClick = { addAdminFn }>添加</Button>
</Space>
</Drawer>
{/* 1.管理员列表 */}
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
{/* 3.编辑管理员数据 */}
<Modal
title="更新管理员信息"
visible={isModalVisible}
onOk={ () => {
console.log('更新数据')
}}
onCancel={ () => { setIsModalVisible(false) }}>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</div>
)
}
export default Index
import request from './../utils/request'
export function getAdminList (params) {
return request.get('/admin/list', { params })
}
export function addAdmin (params) {
return request.post('/admin/add', params)
}
export function updateAdmin (params) {
return request.post('/admin/update', params)
}
import React, { useState, useEffect } from 'react'
import { Table, Drawer, Space, Button, Popconfirm, Input, Select, Tree, Modal } from 'antd'
import { getAdminList, addAdmin, updateAdmin } from '../../api/users'
import menus from './../../router/menus'
function Index() {
// 1.管理员列表
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (
<>
{
index === 0 ? null : <Space>
{/* 3.编辑管理员数据 */}
<Button type="dashed" onClick = { () => {
setIsModalVisible(true)
// 3.修改表单的数据状态
setUadminname(record.adminname)
setUrole(record.role + '')
setUcheckedKeys(record.checkedKeys)
}}>编辑</Button>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
}
</>
)
}
}
]
// 2.添加管理员 - 控制抽屉的显示
const [visible, setVisible] = useState(false)
const showDrawer = () => {
setVisible(true)
}
// 2.添加管理员 - 需要的组件状态
const [adminname, setAdminname] = useState('')
const [password, setPasssword] = useState('')
const [role, setRole] = useState('1')
const [checkedKeys, setCheckedKeys] = useState([]) // 用来记录哪些被选中
const changeRole = (value) => {
setRole(value)
}
const onCheck = (checkedKeys) => {
console.log(checkedKeys)
setCheckedKeys(checkedKeys)
}
const addAdminFn = () => {
const obj = { adminname, password, role, checkedKeys }
console.log(obj)
addAdmin(obj).then(() => {
// 抽屉消失,表单回归初始状态
setVisible(false)
setAdminname('')
setPasssword('')
setRole('1')
setCheckedKeys([])
// 重新渲染一次页面
getAdminList().then(res => {
setAdminList(res.data.data)
})
})
}
// const expandedKeys = ['0-2']
const expandedKeys = []
menus.forEach(item => {
expandedKeys.push(item.key)
})
// 3.编辑管理员数据 - 控制对话框的展示
const [isModalVisible, setIsModalVisible] = useState(false);
// 3.编辑管理员数据 - 输入框的值
const [ uadminname, setUadminname] = useState('')
const [ urole, setUrole] = useState('1')
const [ ucheckedKeys, setUcheckedKeys] = useState([])
const changeURole = (value) => {
setUrole(value)
}
const onUCheck = (checkedKeys) => {
setUcheckedKeys(checkedKeys)
}
return (
<div>
{/* 2.添加管理员 */}
<Button type="primary" onClick = { showDrawer }>添加管理员</Button>
<Drawer
width={ 500 }
title="添加管理员"
placement="right"
closable={true}
onClose={ () => { setVisible(false) }}
visible={visible}
>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { adminname } onChange = { (e) => {
setAdminname(e.target.value)
}} />
<Input type="password" placeholder = "请输入密码" value = { password } onChange = { (e) => {
setPasssword(e.target.value)
}} />
<Select value={ role } onChange = { changeRole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onCheck}
checkedKeys={checkedKeys}
treeData={menus}
/>
<Button type="primary" onClick = { addAdminFn }>添加</Button>
</Space>
</Drawer>
{/* 1.管理员列表 */}
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
{/* 3.编辑管理员数据 */}
<Modal
title="更新管理员信息"
visible={isModalVisible}
onOk={ () => {
const obj = { adminname: uadminname, role: urole, checkedKeys: ucheckedKeys}
console.log('更新数据', obj)
// updateAdmin(obj).then(() => {
// setIsModalVisible(false)
// })
}}
onCancel={ () => { setIsModalVisible(false) }}>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { uadminname } readOnly />
<Select value={ urole } onChange = { changeURole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onUCheck}
checkedKeys={ucheckedKeys}
treeData={menus}
/>
</Space>
</Modal>
</div>
)
}
export default Index
编辑以及删除
import React, { useState, useEffect } from 'react'
import { Table, Drawer, Space, Button, Popconfirm, Input, Select, Tree, Modal, notification } from 'antd'
import { getAdminList, addAdmin, updateAdmin, deleteAdmin } from '../../api/users'
import menus from './../../router/menus'
function Index() {
// 1.管理员列表
const [adminList, setAdminList] = useState([])
useEffect(() => {
getAdminList().then(res => {
setAdminList(res.data.data)
})
}, [])
const columns = [
{
title: '序号',
render: (text, record, index) => <span>{ index + 1 }</span>
},
{
title: '账户',
dataIndex: 'adminname'
},
{
title: '权限',
dataIndex: 'role',
render: (text) => {
return (
text === 2 ? '超级管理员' : '管理员'
)
}
},
{
title: '操作',
render: (text, record, index) => {
return (<Space>
{/* 3.编辑管理员数据 */}
<Button type="dashed" onClick = { () => {
setIsModalVisible(true)
// 3.修改表单的数据状态
setUadminname(record.adminname)
setUrole(record.role + '')
setUcheckedKeys(record.checkedKeys)
}}>编辑</Button>
<Popconfirm
title="确定删除吗?"
onConfirm={() => {
deleteAdmin({ adminid: record.adminid}).then(() => {
getAdminList().then(res => setAdminList(res.data.data))
})
}}
okText="确定"
cancelText="取消">
<Button type="danger">删除</Button>
</Popconfirm>
</Space>
)
}
}
]
// 2.添加管理员 - 控制抽屉的显示
const [visible, setVisible] = useState(false)
const showDrawer = () => {
setVisible(true)
}
// 2.添加管理员 - 需要的组件状态
const [adminname, setAdminname] = useState('')
const [password, setPasssword] = useState('')
const [role, setRole] = useState('1')
const [checkedKeys, setCheckedKeys] = useState([]) // 用来记录哪些被选中
const changeRole = (value) => {
setRole(value)
}
const onCheck = (checkedKeys) => {
console.log(checkedKeys)
setCheckedKeys(checkedKeys)
}
const addAdminFn = () => {
const obj = { adminname, password, role, checkedKeys }
console.log(obj)
addAdmin(obj).then((res) => {
if (res.data.code === '10004') {
notification.warning({
duration: 2,
message: '消息提醒',
description:
'该管理员已存在',
onClick: () => {
},
});
} else {
// 抽屉消失,表单回归初始状态
setVisible(false)
setAdminname('')
setPasssword('')
setRole('1')
setCheckedKeys([])
// 重新渲染一次页面
getAdminList().then(res => {
setAdminList(res.data.data)
})
}
})
}
// const expandedKeys = ['0-2']
const expandedKeys = []
menus.forEach(item => {
expandedKeys.push(item.key)
})
// 3.编辑管理员数据 - 控制对话框的展示
const [isModalVisible, setIsModalVisible] = useState(false);
// 3.编辑管理员数据 - 输入框的值
const [ uadminname, setUadminname] = useState('')
const [ urole, setUrole] = useState('1')
const [ ucheckedKeys, setUcheckedKeys] = useState([])
const changeURole = (value) => {
setUrole(value)
}
const onUCheck = (checkedKeys) => {
console.log(checkedKeys)
setUcheckedKeys(checkedKeys)
}
return (
<div>
{/* 2.添加管理员 */}
<Button type="primary" onClick = { showDrawer }>添加管理员</Button>
<Drawer
width={ 500 }
title="添加管理员"
placement="right"
closable={true}
onClose={ () => { setVisible(false) }}
visible={visible}
>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { adminname } onChange = { (e) => {
setAdminname(e.target.value)
}} />
<Input type="password" placeholder = "请输入密码" value = { password } onChange = { (e) => {
setPasssword(e.target.value)
}} />
<Select value={ role } onChange = { changeRole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onCheck}
checkedKeys={checkedKeys}
treeData={menus}
/>
<Button type="primary" onClick = { addAdminFn }>添加</Button>
</Space>
</Drawer>
{/* 1.管理员列表 */}
<Table
rowKey = { record => record.adminid }
dataSource = { adminList }
columns = { columns } />
{/* 3.编辑管理员数据 */}
<Modal
title="更新管理员信息"
visible={isModalVisible}
onOk={ () => {
const obj = { adminname: uadminname, role: urole, checkedKeys: ucheckedKeys}
console.log('更新数据', obj)
updateAdmin(obj).then(() => {
setIsModalVisible(false)
getAdminList().then(res => setAdminList(res.data.data))
})
}}
onCancel={ () => { setIsModalVisible(false) }}>
<Space direction = "vertical">
<Input placeholder = "请输入账户名" value = { uadminname } readOnly />
<Select value={ urole } onChange = { changeURole }>
<Select.Option value="2">超级管理员</Select.Option>
<Select.Option value="1">管理员</Select.Option>
</Select>
<Tree
checkable // 前面添加复选框
expandedKeys={expandedKeys} // 自动展开哪些二级菜单
onCheck={onUCheck}
checkedKeys={ucheckedKeys}
treeData={menus}
/>
</Space>
</Modal>
</div>
)
}
export default Index
总结
通过本文档的学习,我们掌握了以下几点:
-
环境配置:
- 如何根据不同的环境配置不同的 API 地址。
- 如何创建自定义的
axios
实例并设置请求和响应拦截器。
-
表单页面构建:
- 如何构建一个添加管理员的表单页面,包括输入框、选择框和树形选择组件的使用。
- 如何实现表单数据的提交和验证。
-
数据管理和操作:
- 如何从后端获取管理员列表数据并使用
Table
组件进行渲染。 - 如何实现管理员数据的删除功能,并使用
Popconfirm
组件进行确认提示。 - 如何实现管理员数据的编辑功能,包括模态对话框的显示和数据更新。
- 如何从后端获取管理员列表数据并使用
-
组件库使用:
- 如何使用
antd
组件库中的Input
、Select
、Tree
、Table
、Modal
和Button
等组件构建复杂的用户界面。 - 如何利用
antd
的样式和布局功能提升用户体验。
- 如何使用
通过这些实际案例,我们可以看到 axios
在处理 HTTP 请求方面的强大功能,以及 antd
组件库在构建复杂用户界面时的便捷性和灵活性。希望本文档能为读者在实际项目开发中提供有价值的参考。