没有实现不了的功能 所见即所得
要实现上面的功能也不需要有什么准备 既然都来到这里了 就说明环境上面的你已经搭建完成了 只是为了能实现功能
版本1.0
新建问价DynamicTable.tsx 当然这里是作为组件来说的
引入所用得到的组件功能API 当前所用的antd版本为5.x ,请注意属性兼容!!!
import { Input, Table } from 'antd';
import { useCallback, useMemo, useState } from 'react';
定义组件名称 接收参数 DynamicTable (props里面的数据以及列项不确定直接写Array<any>)
dataSource:数据 columns:列项 这就简单得显示出一个表格
const DynamicTable = (props: { dataSource: Array<any>; columns: Array<any> }) => {
const { dataSource, columns } = props
return (
<Table
className="DynamicTable"
dataSource={dataSource}
bordered={true}
tableLayout={'fixed'}
columns={columns}
pagination={{
total: dataSource.length,
showTotal: total => `共 ${total} 条`,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: [10, 50, 100, 1000]
}}
/>
)
}
export default DynamicTable
内嵌搜索框也就是添加到表格的第一行,首行。那就直接在数据上面做手脚,将搜索框input添加到数据列表中并且位于之首。dataSource[0](仅代表个人想法,也不会有人蠢到去第二页再进行搜索)
在父组件进行使用,给父组件初始化数据
import { useEffect, useMemo, useState } from 'react'
import DynamicTable from '../../components/DynamicTable'
const ManagePage = () => {
const [dataSource, setdataSource] = useState<any[]>([ ])
const [columns, setcolumns] = useState<any[]>([ ])
useEffect(() => {
const data = []
for (let i = 0; i < 100; i++) {
data.push({
key: `${i}i`,
name: `Edward${i} King ${i}`,
age: `${i}32`,
address: `L${i}ondon, Park Lane no. ${i}`,
D: i,
E: `New${i}DEFG`,
F: `New${i}FGHJ`,
G: `New${i}QWER`
})
}
setdataSource([...data])
setcolumns([
{
title: '序号',
dataIndex: 'index',
key: 'index',
render: (text: any, record: any, index: number) => `${index + 1}`,
width: 80,
align: 'center'
},
{
title: 'Name',
dataIndex: 'name',
key: 'name',
align: 'center'
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
align: 'center'
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
align: 'center'
},
{
title: 'D',
dataIndex: 'D',
key: 'D',
align: 'center'
},
{
title: 'E',
dataIndex: 'E',
key: 'E',
align: 'center'
},
{
title: 'F',
dataIndex: 'F',
key: 'F',
align: 'center'
},
{
title: 'G',
dataIndex: 'G',
key: 'G',
align: 'center'
}
])
}, [])
return (
<div id="ManagePage" className="ManagePage">
{useMemo(() => {
return <DynamicTable dataSource={dataSource} columns={columns} />
}, [dataSource, columns])}
</div>
)
}
export default ManagePage
子组件DynamicTable 接收到值,并进行处理
先给获取到的数据添加唯一标识(这里我是自定义的数据,所以传过来接收到就会有key)
现在将接收到的值赋给sliceContent
const sliceContent = useMemo(() => {
const sliceContentData =
dataSource.length > 0
? dataSource.map((item, index) => ({
...item,
key: `${index}`
}))
: []
return sliceContentData
}, [dataSource])
定义searchText和findTitle用来存储输入框输入的值和对应的key
const [searchText, setSearchText] = useState<string>('')
const [findTitle, setFindTitle] = useState<string>('key')
获取到数据中的key值,为每一个key值添加一个input输入框,然后添加到数据的最前面并且给input绑定change事件,传入两个值,一个是value,一个是key
const inputOnChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, s: string) => {
setSearchText(e.target.value)
setFindTitle(s)
}, [])
// 数据标题 -- 数据内容
const dataKeys = useMemo(() => (sliceContent.length > 0 ? Object.keys(sliceContent[0]) : []), [sliceContent])
// 定义过滤input
const columnsInput = useMemo(() => {
const inputColumns: any = {}
for (let index = 0; index < dataKeys.length; index++) {
// 将数据中的每一项赋值为input
inputColumns[dataKeys[index]] = <Input key={dataKeys[index]} placeholder="" onChange={e => inputOnChange(e, dataKeys[index])} />
}
return inputColumns
}, [dataKeys, inputOnChange])
定义完过滤框,就要将过滤框放在数据首行,这里不区分大小写 因为全部转化了
// 数据
const filteredData = useMemo(() => {
if (sliceContent.length === 0) return []
// 将数据进行处理 全部转换为string类型并且都是小写 需要区分大小写就去掉 .toLowerCase()
const filtered = sliceContent.filter(item =>
String(item[findTitle as keyof typeof item])
.toLowerCase()
.includes(searchText.toLowerCase())
)
// 数据的开头填入input搜索框
filtered.unshift(columnsInput)
// 将数据抛出
return filtered
}, [sliceContent, findTitle, searchText, columnsInput])
然后将表格中的数据改成filteredData就可以了,最后可以根据自己项目需求添加其他功能
完整代码:
import { Input, Table } from 'antd'
import { useCallback, useMemo, useState } from 'react'
const DynamicTable = (props: { dataSource: Array<any>; columns: Array<any> }) => {
const { dataSource, columns } = props
console.log('dataSource', dataSource, 'columns', columns)
// 添加key属性 string类型
const sliceContent = useMemo(() => {
const sliceContentData =
dataSource.length > 0
? dataSource.map((item, index) => ({
...item,
key: `${index}`
}))
: []
return sliceContentData
}, [dataSource])
const [searchText, setSearchText] = useState<string>('') // 输入框改变事件 内容
const [findTitle, setFindTitle] = useState<string>('key') // 输入框改变事件 标题
// 输入框change事件
const inputOnChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, s: string) => {
setSearchText(e.target.value)
setFindTitle(s)
}, [])
// 数据标题 -- 数据内容
const dataKeys = useMemo(() => (sliceContent.length > 0 ? Object.keys(sliceContent[0]) : []), [sliceContent])
// 定义过滤input
const columnsInput = useMemo(() => {
const inputColumns: any = {}
for (let index = 0; index < dataKeys.length; index++) {
// 将数据中的每一项赋值为input
inputColumns[dataKeys[index]] = <Input key={dataKeys[index]} placeholder="" onChange={e => inputOnChange(e, dataKeys[index])} />
}
return inputColumns
}, [dataKeys, inputOnChange])
// 数据
const filteredData = useMemo(() => {
if (sliceContent.length === 0) return []
// 将数据进行处理 全部转换为string类型并且都是小写 需要区分大小写就去掉 .toLowerCase()
const filtered = sliceContent.filter(item =>
String(item[findTitle as keyof typeof item])
.toLowerCase()
.includes(searchText.toLowerCase())
)
// 数据的开头填入input搜索框
filtered.unshift(columnsInput)
// 将数据抛出
return filtered
}, [sliceContent, findTitle, searchText, columnsInput])
return (
<Table
className="DynamicTable"
dataSource={filteredData}
bordered={true}
tableLayout={'fixed'}
columns={columns}
pagination={{
total: filteredData.length,
showTotal: total => `共 ${total} 条`,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: [10, 50, 100, 1000]
}}
/>
)
}
export default DynamicTable
上面代码只适合一次搜索,不支持多条件同时搜索
版本2.0
没有进行大更改,就只是改了一下搜索条件,原本是String字符串,改成了数组然后循环查找就好了
修改地方:
1.删除这两行代码
const [searchText, setSearchText] = useState<string>('') // 输入框改变事件 内容
const [findTitle, setFindTitle] = useState<string>('key') // 输入框改变事件 标题
用下面这一个取而代之
const [searchText, setSearchText] = useState<string[]>([])
2.输入框事件
// 输入框change事件
const inputOnChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, s: string) => {
setSearchText(e.target.value)
setFindTitle(s)
}, [])
修改为
const inputOnChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>, s: string) => {
const newSearchText = [...searchText]
newSearchText[dataKeys.indexOf(s)] = e.target.value
setSearchText(newSearchText)
},
[dataKeys, searchText]
)
3.过滤数据方法
// 数据
const filteredData = useMemo(() => {
// 将数据进行处理 全部转换为string类型并且都是小写 需要区分大小写就去掉 .toLowerCase()
const filtered = sliceContent.filter(item =>
String(item[findTitle as keyof typeof item])
.toLowerCase()
.includes(searchText.toLowerCase())
)
// 数据的开头填入input搜索框
filtered.unshift(columnsInput)
// 将数据抛出
return filtered
}, [sliceContent, findTitle, searchText, columnsInput])
修改为
// 数据
const filteredData = useMemo(() => {
if (sliceContent.length === 0) return []
const filtered = sliceContent.filter(item => {
for (let i = 0; i < dataKeys.length; i++) {
const key = dataKeys[i]
const searchValue = searchText[i] || ''
if (!String(item[key]).toLowerCase().includes(searchValue.toLowerCase())) {
return false
}
}
return true
})
filtered.unshift(columnsInput)
return filtered
}, [sliceContent, searchText, dataKeys, columnsInput])
完整代码:
import { Input, Table } from 'antd'
import { useCallback, useMemo, useState } from 'react'
const DynamicTable = (props: { dataSource: Array<any>; columns: Array<any> }) => {
const { dataSource, columns } = props
// 添加key属性 string类型
const sliceContent = useMemo(() => {
const sliceContentData =
dataSource.length > 0
? dataSource.map((item, index) => ({
...item,
key: `${index}`
}))
: []
return sliceContentData
}, [dataSource])
const [searchText, setSearchText] = useState<string[]>([])
// 数据标题 -- 数据内容
const dataKeys = useMemo(() => (sliceContent.length > 0 ? Object.keys(sliceContent[0]) : []), [sliceContent])
const inputOnChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>, s: string) => {
const newSearchText = [...searchText]
newSearchText[dataKeys.indexOf(s)] = e.target.value
setSearchText(newSearchText)
},
[dataKeys, searchText]
)
// 定义过滤input
const columnsInput = useMemo(() => {
const inputColumns: any = {}
for (let index = 0; index < dataKeys.length; index++) {
// 将数据中的每一项赋值为input
inputColumns[dataKeys[index]] = <Input defaultValue={searchText[index]} key={dataKeys[index]} placeholder="" onChange={e => inputOnChange(e, dataKeys[index])} />
}
return inputColumns
}, [dataKeys, inputOnChange])
// 数据
const filteredData = useMemo(() => {
if (sliceContent.length === 0) return []
const filtered = sliceContent.filter(item => {
for (let i = 0; i < dataKeys.length; i++) {
const key = dataKeys[i]
const searchValue = searchText[i] || ''
if (!String(item[key]).toLowerCase().includes(searchValue.toLowerCase())) {
return false
}
}
return true
})
filtered.unshift(columnsInput)
return filtered
}, [sliceContent, searchText, dataKeys, columnsInput])
return (
<Table
className="DynamicTable"
dataSource={filteredData}
bordered={true}
tableLayout={'fixed'}
columns={columns}
pagination={{
total: filteredData.length,
showTotal: total => `共 ${total} 条`,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: [10, 50, 100, 1000]
}}
/>
)
}
export default DynamicTable
使用中有任何报错欢迎私信询问