繁体   English   中英

具有 Reactjs 和材质 UI 的可重用表格组件

[英]Reusable table component with Reactjs and material UI

我来自Vue.js Vuetify.js背景。 Vuetify.jsv-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM