1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > react使用antd-design动态渲染组件 封装通用modal弹出form表单组件 table组件(传数据出页面)

react使用antd-design动态渲染组件 封装通用modal弹出form表单组件 table组件(传数据出页面)

时间:2021-05-23 06:55:42

相关推荐

react使用antd-design动态渲染组件 封装通用modal弹出form表单组件 table组件(传数据出页面)

react使用antd-design封装通用modal弹出form表单组件、table组件并附带1.upload上传图片转base64、2.批量插入excel表格数据

页面展示效果

第一步项目中创建CommonForm.js文件对antd-design中Form组件封装

import {Image, Form, Input, Button, Radio, Select, TimePicker, Checkbox, Upload, message } from "antd";import React, {Component } from "react";import {InboxOutlined } from '@ant-design/icons';import RichText from "../RichText/RichText";const layout = {labelCol: {span: 6 },wrapperCol: {span: 12 },};const tailLayout = {wrapperCol: {offset: 6,span: 12,},};const CheckboxGroup = Checkbox.Group;const url = "http://127.0.0.1:5001/";class CommonForm extends Component {constructor(props) {super(props)const excelName = this.props.excelName //当前导出excel的文件名称(由)this.state = {url: "",pr: {customRequest: this.customRequest,showUploadList: false, // 不展示文件列表beforeUpload: this.beforeUpload},prexcel: {// 发到后台的文件参数名name: 'file',// 接受的文件类型accept: '.xls,.xlsx',// 上传的地址action: url + "api/ExcelFile",// 是否展示上传的文件showUploadList: false,// 上传的参数data: {type:excelName},// 设置上传的请求头部,IE10 以上有效headers: {authorization: 'authorization-text',},// 上传文件前的钩子函数beforeUpload() {message.loading('正在导入中...');return true;},// 上传文件改变时的状态onChange(info) {if (info.file.status !== 'uploading') {console.log(info.file, info.fileList);}if (info.file.status === 'done') {if (info.file.response.code !== 200) {setTimeout(() => {message.destroy();message.error(info.file.response.message);});} else {this.props.importSuccessCallback && this.props.importSuccessCallback();setTimeout(() => {message.destroy();message.success('导入成功');});}} else if (info.file.status === 'error') {setTimeout(() => {message.destroy();message.error('导入失败');});}},}};}/**获取file,通过FileReader获取图片的 base64*/customRequest = (option) => {const formData = new FormData();formData.append("files[]", option.file);const reader = new FileReader();reader.readAsDataURL(option.file);reader.onloadend = (e) => {this.setState({url: e.target.result})//将base64前面类型截取let noPrefix = e.target.result.replace(/^data:image\/\w+;base64,/, '')this.props.base64url(noPrefix); //将处理好的base64传回当前调用的组件// console.log(e.target.result);// 打印图片的base64if (e && e.target && e.target.result) {option.onSuccess();}};}/***上传验证格式及大小*/beforeUpload = (file) => {const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";if (!isJpgOrPng) {message.error("只能上传JPG或PNG文件!");return false;}const isLt2M = file.size / 1024 / 1024 / 1024 <= 500;if (!isLt2M) {message.error("图片大小需小于500kb!");return false;}return isJpgOrPng && isLt2M;}formRef = React.createRef()onFinish = (values) => {this.props.Modal.submit(values)}onValuesChange = (values, allValues) => {if (this.props.FormOnChange) {this.props.FormOnChange(allValues)}}normFile = (e) => {if (Array.isArray(e)) {return e;}return e && e.fileList;};componentDidMount() {this.setState({url: ""})}//根据传回来的类型进行分类标签创建render() {return (<><Formref={this.formRef}{...layout}// labelCol={this.props.isInline ? {span: 24,off }: { span: 4 }}// wrapperCol={this.props.isInline ? { span: 24 }: { span: 12 }}name="basic"key="basic"layout={this.props.isInline ? "inline" : "horizontal"}onFinish={this.onFinish}onValuesChange={this.onValuesChange}initialValues={this.props.defaultValue}>{this.props.Form.length ? (this.props.Form.map((item, i) => {return this.createForm(item, i)})) : (<></>)}<Form.Item {...tailLayout} ><Button key="button" type="primary" htmlType="submit" >确定</Button></Form.Item></Form></>)}copyFormValue(item) {setTimeout(() => {const key = item.namevar obj = {}obj[key] = item.valuethis.formRef.current.setFieldsValue(obj)}, 100);}onChange(checkedValues) {// console.log('checked = ', checkedValues);}createForm(item, i) {this.copyFormValue(item)switch (item.type) {case "input":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请输入您的${item.label}` }]}><Input placeholder={item.placeholder} disabled={item.isDisable} /></Form.Item>case "radio":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请选择您的${item.label}` }]}>{item.isGroup ? (<Radio.Group placeholder={item.placeholder}>{item.radioArr.map((radio, index) => {return (<Radio key={index} value={radio.value}>{radio.label}</Radio>)})}</Radio.Group>) : (<>{/* {radio:{label:"",value:""}}*/}<Radio value={item.radio.value}>{item.radio.label}</Radio></>)}</Form.Item>case "select":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请选择您的${item.label}` }]}><Selectplaceholder="akjsgdjahgsdjh"onChange={item.onChange}>{item.option.length ? (item.option.map((select, index) => {return (<Select.Option key={index} value={select.id}>{select.Name}</Select.Option>)})) : (<>return (<Select.Option key="none" value="">暂无数据</Select.Option>)</>)}</Select></Form.Item>case "textarea":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请输入您的${item.label}` }]}><Input.TextArea placeholder={item.placeholder} /></Form.Item>case "upload":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请选择要上传的图片` }]}valuePropName="fileList" getValueFromEvent={this.normFile}><Upload.Dragger {...this.state.pr}><p className="ant-upload-drag-icon"><InboxOutlined /></p><p className="ant-upload-text">单击或拖动文件到该区域进行上传</p><p className="ant-upload-hint">支持单个或批量上传</p><Image preview={false} src={this.state.url} /></Upload.Dragger></Form.Item>// 多选case "multiple":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请选择您的${item.label}` }]}></Form.Item>//checkboxcase "checkbox":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请选择您的${item.label}` }]}><CheckboxGroup placeholder={item.placeholder} defaultValue={item.defaultValue} options={item.option} onChange={this.onChange} /></Form.Item>//checkboxcase "timepicker":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请选择您的${item.label}` }]}><TimePicker placeholder={item.placeholder} onChange={item.onChange} /></Form.Item>case "richtext":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{message: `请选择您的${item.label}` }]}><RichText that={this.props.that} ></RichText></Form.Item>case "uploadexcel":return <Form.Itemlabel={item.label}name={item.name}key={i}valuePropName="fileList" getValueFromEvent={this.normFile}><Upload.Dragger {...this.state.prexcel}><p className="ant-upload-drag-icon"><InboxOutlined /></p><p className="ant-upload-text">单击或拖动文件到该区域进行上传</p><p className="ant-upload-hint">支持单个或批量上传</p></Upload.Dragger></Form.Item>default:return (<></>)}}}export default CommonForm;

第二步创建CommonModal.js对antd-design中Table组件进行封装

import React, {Component } from 'react';import {Table, Button, Row, Col, Form, Input, DatePicker } from 'antd';import "./CommonTable.css"import {Fragment } from 'react';import ExportJsonExcel from 'js-export-excel'; //引入导出excel表格控件const style = {padding: '8px 0' };class CommonTable extends Component {constructor(props) {super(props)this.state = {filteredInfo: null,sortedInfo: null,current: 1,ordersUpdated: [{vslName: "S",docId: "!",test: "asdjhagsdjh"}],selectedRowKeys: [],//选中行数组};}componentDidMount() {}handleChange = (pagination, filters, sorter) => {console.log(pagination, filters, sorter)this.setState({filteredInfo: filters,sortedInfo: sorter,});};//导出excelclearFilters = () => {this.setState({filteredInfo: null });};clearAll = () => {this.setState({filteredInfo: null,sortedInfo: null,});};setAgeSort = () => {this.setState({sortedInfo: {order: 'descend',columnKey: 'age',},});};onChange = (page, pagesize) => {this.setState({current: page,});// eslint-disable-next-lineif (this.props.totalpage != undefined) {this.props.that.initFun(page, pagesize)}};createForm(item, i) {switch (item.type) {case "input":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请输入您的${item.label}` }]}><Input placeholder={item.placeholder} disabled={item.isDisable} /></Form.Item>case "timepicker":return <Form.Itemlabel={item.label}name={item.name}key={i}rules={[{required: item.isRequired, message: `请输入您的${item.label}` }]}><DatePicker placeholder={item.placeholder} /></Form.Item>default:break;}}onFinish = (values) => {this.props.queryTable(values)}reload = () => {this.props.reloadFun();}//选中行数据‘onSelectChange = selectedRowKeys => {console.log('selectedRowKeys changed: ', selectedRowKeys);this.setState({selectedRowKeys})};ExportToExcel = (tabledata) => {var option = {}let resdata = []let sheetfilter = []let sheetheader = []tabledata.forEach(element => {this.state.selectedRowKeys.forEach(item => {// eslint-disable-next-lineif (element.id == item) {resdata.push(element)}})});this.props.TableColumns.forEach(element => {sheetfilter.push(element.dataIndex)sheetheader.push(element.title)});console.log(this.props.excelName)option.fileName = this.props.excelName //导出的Excel文件名option.datas = [{sheetData: resdata,sheetName: 'sheet',sheetFilter: sheetfilter,sheetHeader: sheetheader,}]var toExcel = new ExportJsonExcel(option);toExcel.saveExcel();}//配置table全选render() {const {selectedRowKeys } = this.state;const rowSelection = {selectedRowKeys,onChange: this.onSelectChange,selections: [Table.SELECTION_ALL,Table.SELECTION_INVERT,Table.SELECTION_NONE,{key: 'odd',text: 'Select Odd Row',onSelect: changableRowKeys => {let newSelectedRowKeys = [];newSelectedRowKeys = changableRowKeys.filter((key, index) => {if (index % 2 !== 0) {return false;}return true;});this.setState({selectedRowKeys: newSelectedRowKeys });},},{key: 'even',text: 'Select Even Row',onSelect: changableRowKeys => {let newSelectedRowKeys = [];newSelectedRowKeys = changableRowKeys.filter((key, index) => {if (index % 2 !== 0) {return true;}return false;});this.setState({selectedRowKeys: newSelectedRowKeys });},},],}return (<><Row justify="space-between" align="center" style={style} >{this.props.ButtonArr ? (this.props.ButtonArr.map((item, i) => {return (<Col span={1} key={i} flex={1}><Button type={item.type} onClick={item.ClickFun}>{item.ButtonText}</Button></Col>)})) : (<Fragment />)}<Formlayout="inline"ref={this.formRef}// labelCol={this.props.isInline ? {span: 24,off }: { span: 4 }}// wrapperCol={this.props.isInline ? { span: 24 }: { span: 12 }}name="basic"key="basic"onFinish={this.onFinish}>{this.props.searchOption ? (this.props.searchOption.map((item, i) => {return this.createForm(item, i)})) : (<></>)}{this.props.searchOption ? (<Form.Item><Row><Col style={{marginRight: "10px"}}><Button key="button" type="primary" htmlType="submit">查询</Button></Col><Col><Button key="clearbutton" onClick={this.reload}>重置</Button></Col></Row></Form.Item>) : (<Fragment />)}<Form.Item><Button key="daochu" type="danger" onClick={() => {this.ExportToExcel(this.props.TableData) }}>导出 Excel</Button></Form.Item></Form></Row><TablescrollborderedrowSelection={rowSelection}loading={this.props.Loading}columns={this.props.TableColumns}dataSource={this.props.TableData}pagination={{showSizeChanger: true,showQuickJumper: true,current: this.state.current,total: this.props.totalpage,onChange: this.onChange,pageSizeOptions: [10, 20, 50, 100]}}/></>);}}export default CommonTable;

第三步创建CommonModal.js对antd-design中Modal组件进行封装

import React, {Component } from 'react';import {Modal } from 'antd';import CommonForm from "../Form/CommonForm";//import CommonTable from '../Table/CommonTable';//(CommonTable为通用封装的table组件)import {Fragment } from 'react';class CommonModal extends Component {// eslint-disable-next-lineconstructor(props){super(props)}render() {return( <><Modaltitle={this.props.Modal.title} //弹出框titlevisible={this.props.Modal.isOpen} //弹出框是否打开footer={null} //弹出框底部按钮onCancel={this.props.Modal.cancel} //弹出框取消事件width={this.props.Modal.width} //弹出框的宽度centered={true}><CommonFormexcelName={this.props.excelName} //需要批量上传的excel参数that={this.props.that} //传入父组件 ,作用:可调用父组件中的属性及方法FormOnChange={this.props.FormOnChange} //监听表单值变化事件base64url={this.props.base64url} //为父组件base64传值initForm={this.props.initForm} Form={this.props.Form} isInline = {this.props.isInline} Modal={this.props.Modal} ></CommonForm></Modal></>)}};export default CommonModal;

第四步:调用页面中使用

import React, {Component } from 'react';import CommonTable from "../../Components/Table/CommonTable"import CommonModal from "../../Components/Modal/CommonModal"import CommonDelete from "../../Components/Modal/CommonDelete" //(CommonDelete 可以自行删掉,封装的一个小弹窗)import {Space, message } from "antd"import {API_GET_ROLE, API_ADD_ROLE,API_GET_ROLE_AUTH,API_UPDATE_ROLE,API_UPDATE_ROLE_AUTH} from '../../Helper/Role'; //这里全部是接口class RoleList extends Component {constructor(props) {super(props)this.state = {TableData: [],TableColumns: [], searchOption: [],ButtonArr: [],Modal: {title: "",isOpen: false,width: 0,submit: Function,cancel: Function},DeleteModal: {},Form: [],Loading: true,excelName:"角色列表"}}SetAuth = async (row) => {console.log("这里是操作中的按钮的方法")}EditTableFun = (row) => {this.setState({Form: [{type: "input",name: "name",label: "角色名称",value: row.name},{type: "textarea",name: "note",label: "角色备注",value: row.note},],Modal: {title: "编辑角色",isOpen: true,width: 600,submit: async (values) => {console.log(values.name)console.log(values.note)//这个是按钮的点击方法},cancel: () => {//这个是弹窗取消事件let originModal = this.state.ModaloriginModal.isOpen = false;this.setState({Modal: originModal})},row: row}})}//点击查询事件 async queryTable(values) {//这个是查询按钮// eslint-disable-next-lineif (values.name == undefined) {message.error("查询字段不能为空!")return}let res = await API_GET_ROLE({name: values.name });switch (res.data.response) {case "success":this.that.setState({TableData: res.data.results})//console.log(this.that.state)break;default:break;}}async reloadFun() {//console.log("重置")let res = await API_GET_ROLE();switch (res.data.response) {case "success":this.that.setState({TableData: res.data.results})break;default:break;}}cancel() {let originModal = this.state.ModaloriginModal.isOpen = false;this.setState({Modal: originModal})this.initFun();}isDeleteWin(row) {//弹出确认框console.log("这个是删除事件")}async initFun() {//初始化table数据事件const res = await API_GET_ROLE({})console.log(res)switch (res.data.response) {case "success":console.log("给table表格赋值")this.setState({Loading: false,TableData: res.data.results,})break;default:this.setState({Loading: false})break;}}componentDidMount() {//请求数据存放tablethis.initFun();//初始化页面所需组件this.setState({Loading: false,TableData: [],TableColumns: [{title: '角色名称',dataIndex: 'name',width: 180},{title: '备注',dataIndex: 'note',},{title: '操作',key: 'action',fixed: 'right',width: 200,render: (text, row) => (<Space size="middle">{/* eslint-disable-next-line */}<a onClick={() => {this.SetAuth(row) }}>设置权限</a>{/* eslint-disable-next-line */}<a onClick={() => {this.EditTableFun(row) }}>编辑</a>{/* eslint-disable-next-line */}<a onClick={() => {this.isDeleteWin(row) }}>删除</a></Space>),}],//这个是table上方按钮数组ButtonArr: [{ButtonText: "添加角色",type: "primary",ClickFun: () => {//打开添加人员的窗口this.setState({Form: [{type: "input",name: "name",label: "角色名称",isRequired: true,value: ""},{type: "textarea",name: "note",isRequired: false,label: "角色备注",value: ""},],Modal: {title: "添加角色",isOpen: true,width: 600,submit: async (values) => {const res = await API_ADD_ROLE({Name: values.name,Note: values.note,});switch (res.data.response) {case "success":message.success("添加成功");//刷新tablethis.cancel();break;default:message.error(res.data.results);break;}},cancel: () => {let originModal = this.state.ModaloriginModal.isOpen = false;this.setState({Modal: originModal})}}})}}],//searchOption搜索栏form元素searchOption: [{type: "input",name: "name",isRequired: false,label: "角色名称",placeholder: "请输入角色名称",value: ""},]})}render() {return (<><CommonDelete Modal={this.state.DeleteModal}></CommonDelete><CommonModal Form={this.state.Form} Modal={this.state.Modal}></CommonModal><CommonTableexcelName={this.state.excelName}initFun={this.initFun}queryTable={this.queryTable}Loading={this.state.Loading}searchOption={this.state.searchOption}that={this}ButtonArr={this.state.ButtonArr}TableColumns={this.state.TableColumns}reloadFun={this.reloadFun}TableData={this.state.TableData}></CommonTable></>)}}export default RoleList;

满足基本管理系统需求,如需加功能,可在封装组件中直接编写,此demo没有样式,样式自加

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。