React hooks+typescript+Antd 简易回收站
最近学习阶段,自己写了一个小练习巩固基础,代码有少量注释,写的不好勿喷
示例 运行结果如下
因为是自己做练习,所以文件都写在一个目录里面
目录结构如下
index.tsx的代码
import React from 'react'
import { Tabs, Card } from 'antd';
import { observer } from 'mobx-react'
import './index.css'
import First from './First'
import Second from './second';
const Recycle = observer(() => {
const { TabPane } = Tabs;
function callback(key: any) {
// console.log(key);
}
return (
<>
<Card>
<Tabs defaultActiveKey="1" onChange={callback}>
<TabPane tab="文件" key="1">
<First />
</TabPane>
<TabPane tab="回收站" key="2">
<Second/>
</TabPane>
</Tabs>
</Card>
</>
)
})
export default Recycle
FirstStore.ts代码
import React from 'react'
import { observable, action } from 'mobx'
export interface FristOption {
key?: number,
name: string,
size?: string,
type?: string,
person?: string,
time?: string,
}
class FirstStore {
@observable datas: any[] = [];
//回收站数据
@observable Tdatas: any[] = [];
//获取格式化时间
@action getNowDate = () => {
const date = new Date();
let month: string | number = date.getMonth() + 1;
let strDate: string | number = date.getDate();
let Hours: string | number = date.getHours()
let Minutes: string | number = date.getMinutes()
let Seconds: string | number = date.getSeconds()
if (month <= 9) {
month = "0" + month;
}
if (strDate <= 9) {
strDate = "0" + strDate;
}
if (Hours <= 9) {
Hours = "0" + Hours;
}
if (Minutes <= 9) {
Minutes = "0" + Minutes;
}
if (Seconds <= 9) {
Seconds = "0" + Seconds;
}
return date.getFullYear() + "-" + month + "-" + strDate + " "
+ Hours + ":" + Minutes + ":" + Seconds;
}
//上传文件,恢复文件
@action addData(item:any) {
const newData = this.datas;
console.log(item.size);
//文件类型修改
let index = item.name.lastIndexOf('\.')
let Type = item.name.substring(index+1, item.name.length);
//保存要添加的数据
const saveData: FristOption = ({
key: this.datas.length,
name: item.name,
size: item.size,
type: Type,
person: "111",
time: this.getNowDate(),
})
newData.splice(this.datas.length+1, 0, saveData)
this.datas = [...newData]
}
//删除文件
@action delData(item: any) {
//添加回收站数据
if (item) {
const newitem = this.Tdatas.slice();
newitem.push({
key: this.Tdatas.length,
name: item.name,
size: item.size,
type: item.type,
person: item.person,
time: this.getNowDate(),
})
this.Tdatas = [...newitem]
}
//删除
const newData = this.datas.slice();
let i = newData.findIndex((datas) => datas.name === item.name);
newData.splice(i,1)
this.datas=[...newData]
}
//回收站删除文件
@action delTData(item: any) {
const newData = this.Tdatas.slice();
let i = newData.findIndex((datas) => datas.name === item.name);
newData.splice(i, 1)
this.Tdatas = [...newData]
}
}
export default React.createContext(new FirstStore())
First.tsx代码
import React, { useState, useContext } from 'react'
import { Table, Button, message, Upload, Tooltip } from 'antd';
import { observer } from 'mobx-react'
import Store from './FirstStore'
import { DeleteOutlined, UploadOutlined } from "@ant-design/icons"
import { toJS } from 'mobx';
//import './index.css'
const First = observer(() => {
const store = useContext(Store)
const [RowItems, setRowItems] = useState([])
const columns:any = [
{
title: '名称',
dataIndex: 'name',
sorter: (a: any, b: any) => a.size - b.size,
//文字超过显示...鼠标悬停显示内容
onCell: () => {
return {
style: {
maxWidth: 150,
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
cursor: "pointer"
}
}
},
render: (text: any) => <Tooltip placement="topLeft" title={text}>{text}</Tooltip>
},
{
title: '大小',
dataIndex: 'size',
defaultSortOrder: 'descend',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '类型',
dataIndex: 'type',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '操作者',
dataIndex: 'person',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '更新时间',
dataIndex: 'time',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '操作',
dataIndex: "work",
// 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引
render: (x: any, item: any, index: number) => <DeleteOutlined onClick={() => Deleteicon(item, index)} />
},
];
const Deleteicon = (item: any, index: number) => {
store.delData(item)
}
//复选框
const rowSelection = {
onChange: (selectedRowKeys: any, selectedRows: any) => {
if (selectedRows) {
setRowItems(selectedRows)
}
}
};
//多个删除
const DeleteAll = () => {
if (RowItems) {
for (let i = 0; i < RowItems.length; i++) {
store.delData(RowItems[i])
}
}
}
//上传
const fileChange = (info: any) => {
if (info.file.status !== 'uploading') {
// console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
//成功
//文件大小
if (info.file.size < 1024) {
info.file.size = info.file.size + 'B';
} else if (info.file.size < (1024 * 1024)) {
info.file.size = (info.file.size / 1024).toFixed(2) + 'KB';
} else if (info.file.size < (1024 * 1024 * 1024)) {
info.file.size = (info.file.size / (1024 * 1024)).toFixed(2) + 'MB';
}
else {
info.file.size = (info.file.size / (1024 * 1024 * 1024)).toFixed(2) + 'GB';
}
store.addData(info.file)
// message.success(`${info.file.name} 上传成功`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} .`);
}
}
return (
<>
<div>
<div style={{ marginBottom: 16 }}>
</div>
<Button type="primary" style={{ float: "left", marginBottom: 5, marginRight: 5 }} onClick={DeleteAll}>
批量删除
</Button>
<div style={{ display: "flex", float: "left", marginBottom: 5 }}>
<Upload
name="file"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
onChange={fileChange}
showUploadList={false}
>
<Button icon={<UploadOutlined />} >上传</Button>
</Upload>,
</div>
<Table
rowSelection={rowSelection}
columns={columns}
dataSource={store?.datas}
showSorterTooltip={false}
/>
</div>
</>
)
})
export default First
second.tsx代码
import React, { useState, useContext } from 'react'
import { Table, Menu, Dropdown, Button, Tooltip } from 'antd';
import { observer } from 'mobx-react'
import Store, { FristOption } from './FirstStore'
import { SettingFilled } from "@ant-design/icons"
import { toJS } from 'mobx';
//import './index.css'
const Second = observer(() => {
const store = useContext(Store)
const [RowItems, setRowItems] = useState([])//保存批量选中时的行元素,是一个数组
const [showMenu, setShowMenu] = useState(false)//控制下拉菜单的显示隐藏
const [recoveritem, setRecoveritem] = useState()//保存回收站点击设置图标传来的行数据
const [Recoverindex, setRecoverindex] = useState()//保存回收站点击设置图标传来的行索引
//回收站设置下拉菜单
const menu = (
<Menu style={{ display: showMenu ? "block" : "none" }}>
<Menu.Item onClick={() => { Recover(recoveritem, Recoverindex) }}>
<a target="_blank" rel="noopener noreferrer" >恢复文件</a>
</Menu.Item >
<Menu.Item danger onClick={() => { Delete(recoveritem, Recoverindex) }}>彻底删除</Menu.Item>
</Menu>
);
//回收站恢复文件
const Recover = (item: any, index: any) => {
store.addData(item)
store.delTData(item)
}
//回收站删除文件
const Delete = (item: any, index: any) => {
store.delTData(item)
}
//回收站点击设置图标
const Deleteicon = (item: any, index: any) => {
setRecoveritem(item)
setRecoverindex(index)
setShowMenu(!showMenu)
}
const rowSelection = {
onChange: (selectedRowKeys: any, selectedRows: any) => {
if (selectedRows) {
setRowItems(selectedRows)
}
}
};
//批量恢复
const RecoverAll = () => {
if (RowItems) {
for (let i = 0; i < RowItems.length; i++) {
store.addData(RowItems[i])
store.delTData(RowItems[i])
}
}
}
//批量删除
const delRecoverAll = () => {
store.Tdatas = []
}
const columns :(any)=[
{
title: '名称',
dataIndex: 'name',
sorter: (a: any, b: any) => a.size - b.size,
//文字超过显示...鼠标悬停显示内容
onCell: () => {
return {
style: {
maxWidth: 150,
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
cursor: "pointer"
}
}
},
render: (text: any) => <Tooltip placement="topLeft" title={text}>{text}</Tooltip>
},
{
title: '大小',
dataIndex: 'size',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '类型',
dataIndex: 'type',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '操作者',
dataIndex: 'person',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '删除时间',
dataIndex: 'time',
sorter: (a: any, b: any) => a.size - b.size,
},
{
title: '操作',
dataIndex: "work",
render: (x: any, item: any, index: any) =>
<Dropdown overlay={menu}>
<a className="ant-dropdown-link">
<SettingFilled
onClick={() => { Deleteicon(item, index) }} />
</a>
</Dropdown>
},
];
return (
<>
<div>
<div style={{ marginBottom: 16 }}>
</div>
<Button type="primary" style={{ float: "left", marginBottom: 5, marginRight: 5 }} onClick={RecoverAll}>
批量恢复
</Button>
<Button style={{ float: "left", marginBottom: 5, marginRight: 5 }} onClick={delRecoverAll}>
清空回收站
</Button>
<Table
rowSelection={rowSelection}
columns={columns}
dataSource={store.Tdatas}
/>
</div>
</>
)
})
export default Second
样式布局基本上都是Antd中的,index.css一开始创建了没用上,最后在App.tsx中引用index.tsx组件< Recycle/>就可以运行了。
(有错误请留言哦,互相学习)