后端數據:
用表格實現權限列表
const dataSource = [{key: '1',name: '胡彥斌',age: 32,address: '西湖區湖底公園1號',},{key: '2',name: '胡彥祖',age: 42,address: '西湖區湖底公園1號',},
];const columns = [{title: '姓名',dataIndex: 'name',key: 'name',},{title: '年齡',dataIndex: 'age',key: 'age',},{title: '住址',dataIndex: 'address',key: 'address',},
];<Table dataSource={dataSource} columns={columns} />;
可以通過dataIndex這個值決定將來要將哪一項顯示在table列中
設置好看的圓角按鈕:
<Button type="primary" shape="circle" icon={<SearchOutlined />} />
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag } from 'antd';
import { EditOutlined,DeleteOutlined } from '@ant-design/icons';
import axios from 'axios';function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights").then(res=>{setdataSource(res.data)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '權限名稱',dataIndex: 'title',},{title: '權限路徑',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(key)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />} /><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} /></div>}},];return (<div><Table dataSource={dataSource} columns={columns} /></div>);
}export default RightList;
這個實現的看分頁器或者滾動條
如果不用滾動條的話還可以使用分頁器
Table表格數據實現樹形結構
表格是支持樹形數據的展示的,當數據中有children字段的時候會自動的展示為樹形表格,如果不需要或者配置為其他字段則可以用childrenColumnName進行配置
可以通過設置indentSize以控制每一層的縮進寬度
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag } from 'antd';
import { EditOutlined,DeleteOutlined } from '@ant-design/icons';
import axios from 'axios';function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.datalist[0].children = ""setdataSource(res.data)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '權限名稱',dataIndex: 'title',},{title: '權限路徑',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(key)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />} /><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} /></div>}},];return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一頁顯示幾條數據pageSize:5}}/></div>);
}export default RightList;
?
把children字段改一下首頁就不會展開了
?添加氣泡框
使用對話框和氣泡框都可以實現想要的效果
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.datalist[0].children = ""setdataSource(res.data)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '權限名稱',dataIndex: 'title',},{title: '權限路徑',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />}/><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {console.log('OK',record);},onCancel() {console.log('Cancel');},});console.log('確認刪除')};return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一頁顯示幾條數據pageSize:5}}/></div>);
}export default RightList;
刪除還要同步一下后端的數據,以及之前的一種寫死的寫法要做出改進,否則刪除完一個之后其他的不支持展開了:
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.data// list[0].children = "" 不建議寫死list.forEach(item=>{if(item.children.length===0){item.children = ""}})setdataSource(list)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '權限名稱',dataIndex: 'title',},{title: '權限路徑',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />}/><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {deleteMethod(record)},onCancel() {console.log('Cancel');},});console.log('確認刪除')};const deleteMethod = (record) => {console.log(record)//同步狀態 頁面setdataSource(dataSource.filter(item=>item.id!==record.id))//同步狀態 后端axios.delete(`http://localhost:3000/rights/${record.id}`)}return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一頁顯示幾條數據pageSize:5}}/></div>);
}export default RightList;
但是現在的代碼刪除children會出現問題
刪除孩子就是根據id這個屬性向后端發請求
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { data } from 'react-router-dom';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.data// list[0].children = "" 不建議寫死list.forEach(item=>{if(item.children.length===0){item.children = ""}})setdataSource(list)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '權限名稱',dataIndex: 'title',},{title: '權限路徑',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Button type="primary" shape="circle" icon={<EditOutlined />}/><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {deleteMethod(record)},onCancel() {console.log('Cancel');},});console.log('確認刪除')};const deleteMethod = (record) => {console.log(record);if (record.grade === 1) {// 刪除一級權限//同步狀態 頁面setdataSource(dataSource.filter(item => item.id !== record.id));//同步狀態 后端axios.delete(`http://localhost:3000/rights/${record.id}`);} else {// 找到對應的父級權限//用maplet list = dataSource.map(item => {if (item.id === record.rightId) {//修正children為數組return {...item,children: Array.isArray(item.children) ? item.children.filter(child => child.id !== record.id) : []};}return item;});//同步狀態setdataSource(list);axios.delete(`http://localhost:3000/children/${record.id}`);}};return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一頁顯示幾條數據pageSize:5}}/></div>);
}export default RightList;
需要注意的是要修改children為數組,避免filter方法出錯
點擊氣泡框:
?
有些沒有權限的就禁用:
import React,{useState,useEffect} from 'react';
import { Button,Table, Tag,Modal,Popover, Switch } from 'antd';
import { EditOutlined,DeleteOutlined,ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { data } from 'react-router-dom';
const { confirm } = Modal;function RightList() {const [dataSource,setdataSource]=useState([])useEffect(()=>{axios.get("http://localhost:3000/rights?_embed=children").then(res=>{const list = res.data// list[0].children = "" 不建議寫死list.forEach(item=>{if(item.children.length===0){item.children = ""}})setdataSource(list)})},[])const columns = [{title: 'ID',dataIndex: 'id',render:(id)=>{return <b>{id}</b>}},{title: '權限名稱',dataIndex: 'title',},{title: '權限路徑',dataIndex: 'key',render:(key)=>{return <Tag color='orange'>{key}</Tag>}},{title: '操作',render:(record)=>{return <div><Popover content={<div style={{textAlign:"center"}}><Switch checked= {record.pagepermisson} onChange={()=>SwitchMethod(record)}></Switch>{/* pagepermission是否存在,不存在的話就禁用 */}</div>} title="配置項" trigger={record.pagepermisson === undefined?'':'click'}><Button type="primary" shape="circle" icon={<EditOutlined />} disabled={record.pagepermisson === undefined }/>{/* 如果沒有配置權限,就不顯示 */}</Popover><Button danger type="primary" shape="circle" icon={<DeleteOutlined />} onClick={()=>confirmMethod(record)}/></div>}},];const SwitchMethod = (record) => {record.pagepermisson = record.pagepermisson===1?0:1//同步狀態 頁面setdataSource([...dataSource])if(record.grade===1){// 同步狀態 后端 axios.patch(`http://localhost:3000/rights/${record.id}`,{pagepermisson:record.pagepermisson})}else{axios.patch(`http://localhost:3000/children/${record.id}`,{pagepermisson:record.pagepermisson})}}const confirmMethod = (record) => {confirm({title: 'Do you Want to delete these items?',icon: <ExclamationCircleOutlined />,onOk() {deleteMethod(record)},onCancel() {console.log('Cancel');},});console.log('確認刪除')};const deleteMethod = (record) => {console.log(record);if (record.grade === 1) {// 刪除一級權限//同步狀態 頁面setdataSource(dataSource.filter(item => item.id !== record.id));//同步狀態 后端axios.delete(`http://localhost:3000/rights/${record.id}`);} else {// 找到對應的父級權限//用maplet list = dataSource.map(item => {if (item.id === record.rightId) {//修正children為數組return {...item,children: Array.isArray(item.children) ? item.children.filter(child => child.id !== record.id) : []};}return item;});//同步狀態setdataSource(list);axios.delete(`http://localhost:3000/children/${record.id}`);}};return (<div><Table dataSource={dataSource} columns={columns} pagination={{//一頁顯示幾條數據pageSize:5}}/></div>);
}export default RightList;
彈出氣泡框的展示,配置成為可選項,同步后端數據,?更改狀態,頁面刷新
重視配置
上面的那個對話框因為antd只支持react 15 ~ 18,但是我的拉下來的項目的依賴是react19,所以需要改一下
以及如果json-server的版本不對也會出現莫名其妙的bug(數據拉取不過來)
劃重點