[英]Reusable table component with Reactjs and material UI
我来自Vue.js
Vuetify.js
背景。 Vuetify.js
有v-data.table组件。
我们只需传递标题和项目即可生成一个漂亮的表格。
<v-data-table
:headers="headers"
:items="desserts"
></v-data-table>
如果我们想在表格单元格中添加按钮、图像或类似的东西我们要做的是
<v-data-table :headers="headers" :items="items" >
<template v-slot:item.images="{ item }">
<v-img
v-if="item.images"
max-width="150px"
:src="item.images"
contain
></v-img>
</template>
<template v-slot:item.update="{ item }">
<v-btn
@click="
$router.replace({
path: '/create-product',
query: { id: item.id },
})
"
>
<v-icon>edit</v-icon>
</v-btn></template
>
</v-data-table>
这是非常干净和容易的。
在 React.js 中,我也可以使用它来实现第一件事
export default function ReusableTable({ headers, items }) { return ( <Grid container> <Grid item> <Card> <CardContent> <TableContainer component={Paper}> <Table> <TableHead> <TableRow> {headers.map((header, i) => ( <TableCell key={i}>{header.text.toUpperCase()}</TableCell> ))} </TableRow> </TableHead>{' '} <TableBody> {items.map((item, i) => ( <TableRow key={i}> {headers.map(({ value }) => ( <TableCell key={value}>{item[value]}</TableCell> ))} </TableRow> ))} </TableBody> </Table> </TableContainer> </CardContent> </Card> </Grid> </Grid> ); }
我也在这里传递标题和项目。 我想为表格中的某些列显示按钮、链接、图像、芯片 (UI)。 我如何在 React 世界中实现这一点?
如果我进一步解释,我想传递项目数组(对象数组)。 对象的 imageSRC 属性应使用img
标签呈现。 像那样的东西。
像这样的东西应该工作。 如果有问题中所述的item.images
,这将有条件地呈现图像标签。 接下来,如果item.update
存在,它将渲染一个 Material Button。 或者,它只是呈现item[value]
。
这是缩写代码:
export default function ReusableTable({ headers, items }) { const dynamicRender = (item, value)=>{ if(item && item.images){ return <img src=`${item.images}`/> } else if(item && item.update){ return <Button href="/create-product">Link</Button> } else { return item[value]; } } return ( <TableBody> {items.map((item, i) => ( <TableRow key={i}> {headers.map(({ value }) => ( <TableCell key={value}>{dynamicRender(item, value)}</TableCell> ))} </TableRow> ))} </TableBody> ); }
尝试这样的事情
import React from "react"; import TableContainer from "@material-ui/core/TableContainer"; import Table from "@material-ui/core/Table"; import Paper from "@material-ui/core/Paper"; import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import TableCell from "@material-ui/core/TableCell"; import TableBody from "@material-ui/core/TableBody"; import { getSlots } from 'helpers/Slots' const BaseTable = ({ headers, items, children, ...otherProps }) => { const [actions] = getSlots(['actions'], children) const tableConfig = { size: "small", } const rowConfig = {...otherProps, } const dynamicRenderer = (item, value) => { if (value === 'actions') { return children(item) } else { return item[value] } } return ( <> <TableContainer component={Paper}> <Table {...tableConfig}> <TableHead> <TableRow {...rowConfig}> {headers.map((header, i) => ( <TableCell key={i}>{header.label}</TableCell> ))} </TableRow> </TableHead> <TableBody> {items.map((item, i) => ( <TableRow key={i} {...rowConfig}> {headers.map(({ value }) => ( <TableCell key={value}>{dynamicRenderer(item, value)}</TableCell> ))} </TableRow> ))} </TableBody> </Table> </TableContainer> </> ) } export default BaseTable
然后添加助手
import React from "react"; const Slot = ({ children }) => <>{children}</> const getSlots = ( names, children) => { return names.map(name => { let slot = null; React.Children.forEach(children, child => { if (.React;isValidElement(child)) { return. } if (child.type === Slot && (child.props).name === name) { slot = React;cloneElement(child); } }); return slot; }), } export { Slot, getSlots }
import React, { useState, useEffect } from "react" import Grid from '@material-ui/core/Grid' import BaseTable from 'helpers/Table' import { Slot } from 'helpers/Slots' import PencilBoxOutline from 'mdi-react/PencilBoxIcon' import DeleteOutline from 'mdi-react/DeleteIcon' const headers = [ {value: 'name', label: 'Name'}, {value: 'age', label: 'Age'}, {value: 'gender', label: 'Gender'}, {value: 'registeredDate', label: 'Date of Registration'}, {value: 'requirements', label: 'Semester Requirements'}, {value: 'percentage', label: 'Percentage (%)'}, {value: 'actions', label: 'Actions'}, ] const items = [ { id: 1, requirements: 'Pay at least 50% ', percentage: '10%', name: "John Doe", age: 30, registeredDate: "2021/10/30", gender: "Male" }, { id: 2, requirements: 'Just go with it', percentage: '50%', name: "Jane Doe", age: 40, registeredDate: "2021/10/30", gender: "Female" }, ] const Test = () => { return ( <Grid container spacing={4}> <Grid item xs={12}> <Grid container justifyContent="space-between" spacing={2}> <Grid item></Grid> <Grid item sm={9}></Grid> </Grid> <BaseTable headers={headers} items={items}> {(item) => ( <Slot name="actions"> <PencilBoxOutline onClick={(item) => onOpenDialog(item)}/> <DeleteOutline onClick={(item) => onDelete(item)} /> </Slot> )} </BaseTable> </Grid> </Grid> ) } export default Test
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.