Skip to content

v3-form

配置式表单组件

基于 Json 配置生成表单,可快速完成详情页编辑。vscode 插件 v3-snippets 有提供快捷代码段,可快速生成 json

基础用法

设置 json 格式的表单数组,赋值给 v3-form 的form-items属性

仔细阅读

具体属性功能见下方代码注释

js
const formItems = [
  {
    //设置此属性后 attrs失效
    slot: "自定义插槽",
    //表单组件名称
    tag: "input",
    itemAttrs: {
      //表单字段名称
      label: "姓名",
      //当表单属性inline为false时候可用,配置栅格间隔 默认24
      col: 12,
      // 校验表单rules
      rules: [{ required: true, message: "年龄不能为空", trigger: "click" }],
    },
    // attrs 可设置组件的所有属性(如此组件input则可以设置el-input的所有属性,其他组件相同)
    attrs: {
      key: "name", //表单提交字段名称 需要唯一
      placeholder: "请输入姓名",
    },
    getAttrs(Model) {
      // 返回一个被合并到当前attrs属性里的对象
      return Model.age === "22" ? { disabled: true } : null;
    },
    ifRender(Model) {
      // 返回true/false用于是否显示该字段
      return Model.hobby === 2;
    },
  },
];
vue
<template>
  <div class="form-x">
    <v3-form ref="formRef" :model="editForm" :form-items="formItems" />
  </div>
</template>

赋默认值

表单赋默认值只需要给 model 的参数(editForm)赋值即可

注意

表单对象如果直接等于则会失去响应式,应使用 Object.assign 合并对象; 或者赋值单个属性 editForm.xx = xx

vue
<template>
  <div class="hello">
    <v3-form ref="formRef" :model="editForm" :form-items="formItems" />
  </div>
</template>

<script setup name="example-form">
import { useForm } from "./hooks/useForm";

const props = defineProps({
  oldForm: { type: Object, default: () => ({}) },
});

const { formItems, editForm, formRef } = useForm();

onMounted(() => {
  Object.assign(editForm, props.oldForm);
});
</script>

插槽

在现有组件无法满足表单需求时,可使用插槽或扩展组件

建议

优先推荐扩展组件,可复用,有利于维护

js
const formItems = [
  {
    slot: "cusSpan",
    itemAttrs: {
      label: "自定义",
      col: 12,
    },
  },
];
vue
<template>
  <div>
    <v3-form
      :form-items="formItems">
      <template #cusSpan>
        <span>这是自定义插槽</span>
      </template>
    </v3-form>
  </div>
</template>

表单提交

自定义事件

vue
<template>
  <div class="hello">
    <v3-form ref="formRef"
     @submit="onSubmit" />
     <--使用自定义按钮-->
     <el-button @click="onSave">保存</el-button>
  </div>
</template>
<script setup>

//调用实例校验表单 -- 非自定义按钮无需此操作
function onSave(){
  // 此操作会触发submit自定义事件回调
  formRef.value.submit
}

function onSubmit(){
    //校验成功后的业务逻辑
}
</script>

实例返回 promise

vue
<template>
  <div class="hello">
    <v3-form ref="formRef"/>
    <--使用自定义按钮-->
    <el-button @click="onSave">保存</el-button>
  </div>
</template>
<script setup>
//非自定义按钮无需此操作
function onSave() {
  formRef.value.promiseSubmit().then(()=>{
    //校验成功后的业务逻辑
  })
}
</script>

结合弹窗组件的表单

弹窗抽屉的形式进行表单编辑

js
//hooks/useForm
export function useForm() {
  const editForm = reactive({
    checkboxGroup: ["1"],
  });
  const formRef = ref();
  const formItems = [
    {
      tag: "input",
      itemAttrs: {
        label: "姓名",
        col: 12,
        rules: [{ required: true, message: "年龄不能为空", trigger: "click" }],
      },
      attrs: {
        key: "name",
        placeholder: "请输入姓名",
      },
      getAttrs(Model) {
        // 返回一个被合并到当前attrs属性里的对象
        return Model.age === "22" ? { disabled: true } : null;
      },
    },
    {
      tag: "select",
      itemAttrs: {
        label: "兴趣",
        col: 10,
      },
      attrs: {
        key: "hobby",
        placeholder: "请输入兴趣",
        options: [
          { value: 1, label: "吃饭" },
          { value: 2, label: "睡觉" },
          { value: 3, label: "打豆豆" },
        ],
      },
    },
    {
      tag: "input",
      itemAttrs: {
        label: "年龄",
        rules: [{ required: true, message: "年龄不能为空", trigger: "click" }],
      },
      attrs: {
        key: "age",
        placeholder: "请输入年龄",
      },
      ifRender(Model) {
        return Model.hobby === 2;
      },
    },
    {
      tag: "date",
      itemAttrs: {
        label: "日期",
        col: 12,
      },
      attrs: {
        key: "date",
        "value-format": "yyyy-MM-dd",
      },
    },
    {
      tag: "radio",
      itemAttrs: {
        label: "单选框",
      },
      attrs: {
        value: "1",
        key: "radio",
        options: [
          { value: "1", label: "男" },
          { value: "2", label: "女" },
        ],
      },
    },
    {
      tag: "uploadImg",
      itemAttrs: {
        label: "文章封面",
        col: 24,
      },
      attrs: {
        key: "image_uri",
        limit: 2,
      },
    },
    {
      tag: "checkbox-group",
      itemAttrs: {
        label: "复选框组",
      },
      attrs: {
        key: "checkboxGroup",
        options: [
          { value: "1", label: "复选框1" },
          { value: "2", label: "复选框2" },
          { value: "3", label: "复选框3" },
        ],
      },
    },
    {
      tag: "checkbox",
      itemAttrs: {
        label: "复选框",
      },
      attrs: {
        key: "checkbox",
        value: true,
        label: "复选框",
      },
    },
    {
      tag: "textarea",
      itemAttrs: {
        label: "文本框",
      },
      attrs: {
        key: "textarea",
      },
    },
  ];
  return {
    formRef,
    editForm,
    formItems,
  };
}

提示

表单的属性 footer 如果设置为 true,则使用 v3-form 自带按钮(按钮样式按需求自定义) 保存或者其他逻辑要关闭抽屉,则需要定义const emit = defineEmits(["clsDwr"]) 在需要关闭的时候emit("clsDwr"),如果是弹窗则是clsDlg。如果使用 useDialog 自带按钮(传入 footer 对象),则表单必须暴露一个名为 expose_fn 的函数,一般保存逻辑写在此函数中

vue
//form表单组件(/comprnents/form)
<template>
  <div class="hello">
    <v3-form
      ref="formRef"
      footer
      :model="editForm"
      :form-items="formItems"
      @submit="onSubmit"
    />
    <p style="color:red;text-align:center">
      上方的的提交,重置按钮 通过footer进行隐藏显示
    </p>
  </div>
</template>

<script setup name="example-form">
import { useForm } from "./hooks/useForm";

const props = defineProps({
  oldForm: {
    type: Object,
    default: () => ({}),
  },
});

const emit = defineEmits(["clsDwr"]);

const { formItems, editForm, formRef } = useForm();

onMounted(() => {
  setTimeout(() => {
    Object.assign(editForm, props.oldForm);
  }, 2000);
});

function onSubmit() {
  emit("clsDwr");
}

function expose_fn() {
  formRef.value.submit().then(() => {
    emit("clsDwr");
  });
}

defineExpose({
  expose_fn,
});
</script>

属性

参数说明类型默认值
...支持 el-form 所有属性...必填
model表单数据对象object必填
formItems表单字段项(参见上方代码演示)array必填
inline行内表单模式booleanfalse
submitMsg提交按钮文案(值为 false 时隐藏按钮)string | boolean提交
resetMsg重置按钮文案(值为 false 时隐藏按钮)string | boolean重置
labelWitdh表单域标签的宽度stringauto
footer是否显示底部/右侧按钮booleanfalse
size用于控制该表单内组件的尺寸stringsmall
gutter栅格间隔(当 inline 值为 false 时无效)number24

事件

方法名说明参数
submit表单校验完成后提交
after-reset点击重置按钮会触发该事件

插槽

name说明
item.colSlot自定义表单元素(参见上方代码演示)

Exposes

属性说明类型
handleReset重置表单Function
promiseSubmit表单验证返回 promise 对象Function