Skip to content

效果预览

表单项增删改示例

el-input:
el-select:
去选择
el-cascader:
el-select-multiple:
去选择
el-radio-group:
el-checkbox-group:
el-input-number:
el-date-picker:
el-tree-select:
去选择
el-time-picker:
标题
el-input:
el-radio-group:

示例代码

vue
<template>
  <h3>表单项增删改示例</h3>
  <FastForm />

  <el-space wrap>
    <el-button @click="submit" type="primary">提交</el-button>
    <el-button @click="reset">重置</el-button>
    <el-button @click="remove(true)">删除多个表单项(删除旧值)</el-button>
    <el-button @click="remove(false)">删除多个表单项(保留旧值)</el-button>
    <el-button @click="add">添加el-input2</el-button>
    <el-button @click="edit">修改el-cascader必填</el-button>
    <el-button @click="editNested">修改嵌套列表表单项</el-button>
    <el-button @click="setAllFormConfig(true)">替换整个表单(删除旧值)</el-button>
    <el-button @click="setAllFormConfig(false)">替换整个表单(保留旧值)</el-button>
  </el-space>

  <el-divider>嵌套表单操作示例</el-divider>
  <el-space>
    <el-button @click="addNestedField" type="success">向嵌套列表添加字段</el-button>
    <el-button @click="removeNestedFields(true)" type="danger">删除嵌套表单项(删除旧值)</el-button>
    <el-button @click="removeNestedFields(false)" type="danger">删除嵌套表单项(保留旧值)</el-button>
    <el-button @click="addToSecondGroup" type="info">添加部门选择字段</el-button>
  </el-space>
</template>

<script lang="ts" setup>
import { useForm } from "element-plus-fast-form";
import { watch } from "vue";
import { formConfig, attrs } from "./config";
import { ElMessage } from "element-plus";

const {
  FastForm,
  formValue,
  formRef,
  rawFormValue,
  removeFormConfig,
  addFormConfig,
  setFormConfig,
  setFormConfigs,
} = useForm({
  ...attrs,
  formConfig,
});
const submit = () => {
  if (formRef.value) {
    formRef.value.validate((valid: boolean) => {
      if (valid) {
        ElMessage.warning("查看控制台");
        console.log({ formValue, rawFormValue });
      }
    });
  }
};
const reset = () => {
  if (formRef.value) {
    formRef.value.resetFields();
  }
};
function remove(isRemoveValue: boolean = true) {
  removeFormConfig(["el-input", "el-select", "el-select-multiple", "el-date-picker", "el-radio-group"], isRemoveValue);
  console.log("remove----formValue", formValue);
}
function add() {
  addFormConfig(
    {
      component: "el-input",
      formItemProps: {
        prop: "el-input2",
        label: "el-input2",
        rules: [
          {
            required: true,
            message: "请填写完整",
          },
          {
            validator: (
              _rule: any,
              value: string,
              callback: (arg0?: Error | undefined) => void
            ) => {
              if (/\w/.test(value)) {
                return callback(new Error("请输入非字母数字下划线字符"));
              }
              callback();
            },
            trigger: ["change", "blur"],
          },
        ],
      },
      componentProps: {
        placeholder: "去输入",
      },
    },
    undefined, // targetProp (不指定嵌套位置)
    1          // index (在顶层的第1个位置插入)
  );
}

function edit() {
  setFormConfig("el-cascader", {
    formItemProps: {
      rules: [
        {
          required: true,
          message: "请选择",
          trigger: "change",
        },
      ],
    },
  });
}

function editNested() {
  setFormConfig("children.0.el-input", {
    formItemProps: {
      label: '姓名'
    },
  });

  setFormConfig("children.0.el-radio-group", {
    formItemProps: {
      rules: [{ required: true, message: "请选择" }],
      label: '性别'
    },
  });
}

// 嵌套表单操作示例函数
function addNestedField() {
  // 向第一组(children.0)添加一个新的字段
  addFormConfig(
    {
      component: "el-input",
      formItemProps: {
        prop: "phone",
        label: "联系电话",
        rules: [
          {
            required: true,
            message: "请输入联系电话",
            trigger: "blur"
          }
        ]
      },
      componentProps: {
        placeholder: "请输入联系电话",
        maxlength: 11
      }
    },
    "children.0" // 指定添加到 children 数组的第0组
  );
  ElMessage.success("已向第一组添加联系电话字段");
}

function removeNestedFields(isRemoveValue: boolean = true) {
  // 删除嵌套表单中的多个字段
  removeFormConfig([
    "children.0.phone",        // 删除第一组的联系电话(如果之前添加过)
    "children.0.el-radio-group" // 删除第一组的单选框
  ], isRemoveValue);
  ElMessage.success("已删除指定的嵌套表单项");
  console.log("removeNestedFields----formValue", formValue);
}

function addToSecondGroup() {
  // 注意:这个示例假设children数组至少有两组数据
  // 实际使用时需要确保对应索引的组已存在
  // 这里我们先向第0组添加一个新字段作为示例
  addFormConfig(
    {
      component: "el-select",
      formItemProps: {
        prop: "department",
        label: "所属部门"
      },
      componentProps: {
        placeholder: "请选择所属部门",
        options: [
          { label: "技术部", value: "tech" },
          { label: "产品部", value: "product" },
          { label: "运营部", value: "operation" }
        ]
      }
    },
    "children.0" // 添加到 children 数组的第0组

  );
  ElMessage.success("已向表单组添加部门选择字段");
}

function setAllFormConfig(isRemoveValue: boolean = false) {
  setFormConfigs([
    {
      component: "el-input",
      formItemProps: {
        prop: "el-input",
        label: "el-input",
        rules: [
          {
            required: true,
            message: "请填写完整",
          },
          {
            validator: (
              _rule: any,
              value: string,
              callback: (arg0?: Error | undefined) => void
            ) => {
              if (/\w/.test(value)) {
                return callback(new Error("请输入非字母数字下划线字符"));
              }
              callback();
            },
            trigger: ["change", "blur"],
          },
        ],
      },
      componentProps: {
        placeholder: "去输入",
      },
      defaultValue: '他'
    }], isRemoveValue);
}

watch(
  () => rawFormValue,
  (newValue) => {
    console.log("watch----rawFormValue", newValue);
  },
  { deep: true, immediate: true }
);

watch(
  () => formValue,
  (newValue) => {
    console.log("watch----formValue", newValue);
  },
  { deep: true, immediate: true }
);
</script>
ts
// 新增表单样式配置
export const attrs = {
  colProps: {
    span: 12,
  },
  rowProps: {
    gutter: 24,
  },
  formProps: {
    "label-position": "right",
    "label-suffix": ":",
    "label-width": "160",
  },
};

// 新增表单配置
export const formConfig = [
  {
    component: "el-input",
    formItemProps: {
      prop: "el-input",
      label: "el-input",
      rules: [
        {
          required: true,
          message: "请填写完整",
        },
        {
          validator: (
            _rule: any,
            value: string,
            callback: (arg0?: Error | undefined) => void
          ) => {
            if (/\w/.test(value)) {
              return callback(new Error("请输入非字母数字下划线字符"));
            }
            callback();
          },
          trigger: ["change", "blur"],
        },
      ],
    },
    componentProps: {
      placeholder: "去输入",
    },
    defaultValue: '我'
  },

  {
    component: "el-select",
    formItemProps: {
      prop: "el-select",
      label: "el-select",
    },
    componentProps: {
      placeholder: "去选择",
      options: [
        { label: "男", value: "male" },
        { label: "女", value: "female" },
      ],
    },
  },
  {
    component: "el-cascader",
    formItemProps: {
      prop: "el-cascader",
      label: "el-cascader",
    },
    componentProps: {
      placeholder: "去选择",
      options: [
        {
          label: "艺术",
          value: "艺术",
          children: [
            {
              label: "音乐",
              value: "1-1",
            },
            {
              label: "绘画",
              value: "1-2",
            },
          ],
        },
        {
          label: "体育",
          value: "2",
          children: [
            {
              label: "足球",
              value: "2-1",
            },
            {
              label: "拳击",
              value: "2-2",
            },
          ],
        },
      ],
    },
  },
  {
    component: "el-select",
    formItemProps: {
      prop: "el-select-multiple",
      label: "el-select-multiple",
    },
    componentProps: {
      placeholder: "去选择",
      multiple: true,
      options: [
        { label: "A", value: "A" },
        { label: "B", value: "B" },
      ],
    },
  },
  {
    component: "el-radio-group",
    formItemProps: {
      prop: "el-radio-group",
      label: "el-radio-group",
    },
    componentProps: {
      placeholder: "去选择",
      options: [
        { label: "是", value: "Y" },
        { label: "否", value: "N" },
      ],
    },
  },
  {
    component: "el-checkbox-group",
    formItemProps: {
      prop: "el-checkbox-group",
      label: "el-checkbox-group",
    },
    componentProps: {
      placeholder: "去选择",
      options: [
        { label: "1", value: "1" },
        { label: "2", value: "2" },
      ],
    },
  },
  {
    component: "el-input-number",
    formItemProps: {
      prop: "el-input-number",
      label: "el-input-number",
    },
    componentProps: {
      placeholder: "去输入",
      min: 1,
      max: 99,
      precision: 0,
      "controls-position": "right",
    },
  },
  {
    component: "el-date-picker",
    formItemProps: {
      prop: "el-date-picker",
      label: "el-date-picker",
    },
    componentProps: {
      placeholder: "去输入",
      type: "date",
    },
  },
  {
    component: "el-tree-select",
    formItemProps: {
      prop: "el-tree-select",
      label: "el-tree-select",
    },
    componentProps: {
      placeholder: "去选择",
      data: [
        {
          value: "beijing",
          label: "北京",
          children: [
            {
              value: "chaoyang",
              label: "朝阳",
            },
            {
              value: "tongzhou",
              label: "通州",
            },
          ],
        },
        {
          value: "xiamen",
          label: "厦门",
          children: [
            {
              value: "jimei",
              label: "集美",
            },
            {
              value: "huli",
              label: "湖里",
            },
          ],
        },
      ],
    },
  },
  {
    component: "el-time-picker",
    formItemProps: {
      prop: "el-time-picker",
      label: "el-time-picker",
    },
    componentProps: {
      placeholder: "去选择",
    },
  },

  {
    formItemProps: {
      prop: "children",
      label: "children",
    },
    children: [
      [
        {
          component: "span",
          formItemProps: {},
          componentProps: {
            style: {
              fontSize: "18px",
              marginLeft: "-90px",
            },
          },
          defaultValue: "标题",
          colProps: {
            span: 24,
          },
        },
        {
          component: "el-input",
          formItemProps: {
            prop: "el-input",
            label: "el-input",
            rules: [
              {
                required: true,
                message: "请填写完整",
              },
            ],
          },
          componentProps: {
            placeholder: "去输入",
          },
        },
        {
          component: "el-radio-group",
          formItemProps: {
            prop: "el-radio-group",
            label: "el-radio-group",
          },
          componentProps: {
            placeholder: "去选择",
            options: [
              { label: "是", value: "Y" },
              { label: "否", value: "N" },
            ],
          },
        },
      ],
    ],
  },
];