新增和修改数据,封装一个组件,运用于不同页面和不同类型,form表单中有可编辑的表格(父子传值,antd-Form表单的二次封装)

本文介绍如何创建一个可复用的组件,该组件在不同的页面和场景中用于新增和修改数据。通过封装antd的Form表单,实现父子组件间的数据传递,以实现表格内的编辑功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import React, { Component } from 'react';
import { Table,Button,Input,Icon,Form,message,Modal,Select,DatePicker,Upload,Pagination,Tooltip,InputNumber,Col, Row,Radio,Tabs, Layout} from 'antd';
import { user,service } from '@/utils/ajax';
import {removeEmptyField} from '@/utils';

import './index.scss';
const { Column } = Table;

const FormItem = Form.Item;
const { TextArea } = Input;
const { Option } = Select;   
const { TabPane } = Tabs;
//定义表单内部样式
const FormItemLayout = {
    labelCol: {
      xs: { span: 24 },
      sm: { span: 3 }
    },
    wrapperCol: {
      xs: { span: 24 },
      sm: { span: 21 }
    }
   }; 
   //定义input框的样式
   const FormItemLayoutChild = {
    labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
   }; 
//在react中使用antd创建可编辑的表格,使用createContext( )

const EditableContext = React.createContext();

//1.自己新建两个组件Provider
//2.Provider有一个参数value
//3.在Provider组件内遍历子组件,

const EditableRow = ({ form, index, ...props }) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component {
  state = {
    editing: false,
  };

  toggleEdit = () => {
    const editing = !this.state.editing;
    this.setState({ editing }, () => {
      if (editing) {
        this.input.focus();
      }
    });
  };

  save = e => {
    const { record, handleSave } = this.props;
    this.form.validateFields((error, values) => {
      if (error && error[e.currentTarget.id]) {
        return;
      }
      this.toggleEdit();
      handleSave({ ...record, ...values });
    });
  };

  renderCell = form => {
    this.form = form;
    const { children, dataIndex, record, title } = this.props;
    const { editing } = this.state;
    return editing ? (
      <Form.Item style={
  { margin: 0 }}>
        {form.getFieldDecorator(dataIndex, {
          rules: [
            // {
            //   required: true,
            //   message: `${title} is required.`,
            // },
          ],
          initialValue: record[dataIndex],
        })(<Input ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save} />)}
      </Form.Item>
    ) : (
      <div
        className="editable-cell-value-wrap"
        style={
  { paddingRight: 24 }}
        onClick={this.toggleEdit}
      >
        {children}
      </div>
    );
  };

  render() {
    const {
      editable,
      dataIndex,
      title,
      record,
      index,
      handleSave,
      children,
      ...restProps
    } = this.props;
    return (
      <td {...restProps}>
        {editable ? (
          <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
        ) : (
          children
        )}
      </td>
    );
  }
}
class App extends Component {
    constructor(props){
        super(props);
        this.state = {
            formStatic:[
                {name:'name',attr:{placeholder:'接口名称'}, label:"接口名称:",value:'',rules:[{required:true,message:'接口名称不能为空'}]},
                {name:'type',attr:{placeholder:'服务类型'}, label:"服务类型:",value:'',rules:[{required:true,message:'服务类型不能为空'}]},
                {name:'provider',attr:{placeholder:'服务提供人'}, label:"服务提供人:",value:'',rules:[{required:true,message:'服务提供人不能为空'}]},
                {name:'effectiveDate',attr:{placeholder:'生效日期'}, label:"生效日期:",value:'',rules:[{required:false,message:'生效日期不能为空'}]},
                {name:'description',attr:{placeholder:'服务描述'}, label:"服务描述:",value:'',rules:[{required:true,message:'服务描述不能为空'}]},
                {name:'normalCode',attr:{placeholder:'成功返回值'}, label:"成功返回值:",value:'',rules:[{required:true,message:'成功返回值不能为空'},{pattern: new RegExp(/^[0-9]{1,}$/, "g") , message: '状态码只允许包含0及以上纯数字!'}]},

            ],
            returnExample:'',
            btnValue:"测试",
            url:'',
            serviceTypeData:[],
            requestTypeData:[],
            Params:[{id:0,key:"",value:''}],
            Headers:[{id:0,key:"",value:''}],
            bodytext:'',
            tabsActive:"Params",
            columns:[
                {
                    title: 'key',
                    dataIndex: 'k
### 实现 Vue 中父组件调用子组件必填表单验证并滚动到错误位置 在 Vue 应用程序中实现这一功能涉及多个方面,包括但不限于父子组件通信、表单验证以及页面内滚动。下面详细介绍如何达成此目标。 #### 使用自定义事件 `$refs` 进行跨组件交互 为了使父组件能够触发子组件中的特定方法(如执行表单验证),可以利用 `ref` 属性来获取对子组件实例的引用,并通过定义的方法来进行操作[^1]。当需要验证时,父组件可以通过这个引用直接调用子组件内的公共方法完成验证逻辑。 对于滚动行为,则可以在检测到有未通过验证的字段之后计算其相对于视口的位置并通过 JavaScript 的原生 API 或者第三方库(比如 vue-scrollto)平滑地移动至相应区域[^2]。 #### 子组件设计:封装组件表单项 考虑到希望在外层包裹 `<el-form-item>` 来辅助校验工作,建议如下构建子组件: ```html <template> <div class="upload-container"> <!-- 将 el-form-item 设置为可选参数 --> <el-form-item :prop="formItemProp" v-if="showFormItemWrapper" :rules="[{ required: true, message: '请上文件', trigger: ['change'] }]" ref="fileUploadRef"> <el-upload ...>...</el-upload> </el-form-item> <!-- 如果不需要额外包装则直接展示 upload 组件 --> <el-upload v-else ...></el-upload> </div> </template> <script setup lang="ts"> import { defineProps, toRefs, computed } from "vue"; const props = defineProps({ showFormItemWrapper: Boolean, formItemProp: String, }); // 计算属性决定是否显示外层 wrapper const shouldShowWrapper = computed(() => !!props.showFormItemWrapper && !!props.formItemProp); </script> ``` 上述代码片段展示了如何基于入的 prop 动态控制是否应用外部的 `<el-form-item>` 包裹器。这允许更灵活地集成不同的 UI 需求场景下使用相同的上控件。 #### 父组件逻辑:发起验证请求及处理反馈 为了让整个流程更加流畅,在父级容器里应当提供一个按钮或其他方式让用户主动提交数据;点击后会向所有必要的子部件发送命令去启动它们各自的检验过程。一旦发现任何不符合规定之处即刻停止进一步动作并将焦点转移到第一个出错的地方。 ```javascript methods: { async validateAndScroll() { let isValid = await this.$refs.childComponent.validate(); // 假设 childComponent 是上面提到的那个带上功能的小零件 if (!isValid) { const firstErrorElement = document.querySelector('.el-form-item.is-error'); if (firstErrorElement) { window.scrollTo({ top: firstErrorElement.offsetTop - 80, behavior: 'smooth' }); } } return isValid; }, } ``` 这段脚本说明了怎样从父级视角出发协调各部分之间的协作关系——先尝试让各个独立单元自行检查状态,再依据返回的结果采取适当措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值