Skip to content

Form 表单

表单目前包含 输入框, 下拉选择, 开关 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。

TIP

ps: 表单控件目前不全,待完善

基本用法

最基础的表单包括各种输入表单项,比如inputselectswitch等。(目前只开发了这三个 🤣) 在每个 from 组件中,需要使用 from-item 组件来包裹每个表单项,用于获取值与校验。

<script lang="ts" setup>
import { reactive, ref } from "vue";
import { ErMessage } from "eric-ui";

const form = reactive({
  name: "",
  region: "",
  delivery: false,
  desc: "",
});

const options = ref([
  { value: "beijing", label: "Zone One" },
  { value: "shanghai", label: "Zone Two" },
]);

const onSubmit = () => {
  ErMessage.success("submit!");
};
</script>

<template>
  <er-form :model="form">
    <er-form-item label="Activity name">
      <er-input v-model="form.name" />
    </er-form-item>
    <er-form-item label="Activity zone">
      <er-select
        v-model="form.region"
        placeholder="please select your zone"
        :options="options"
      />
    </er-form-item>
    <er-form-item label="Instant delivery">
      <er-switch v-model="form.delivery" />
    </er-form-item>
    <er-form-item label="Activity form">
      <er-input v-model="form.desc" type="textarea" />
    </er-form-item>
    <er-form-item>
      <er-button type="primary" @click="onSubmit">Create</er-button>
      <er-button>Cancel</er-button>
    </er-form-item>
  </er-form>
</template>

对齐方式

通过 label-position 属性可以控制表单项的左右对齐方式。

<script lang="ts" setup>
import { reactive, ref } from "vue";
import { ErMessage, type FormProps } from "eric-ui";

const form = reactive({
  name: "",
  region: "",
  delivery: false,
  desc: "",
});
const options = ref([
  { value: "beijing", label: "Zone One" },
  { value: "shanghai", label: "Zone Two" },
]);
const labelPosition = ref<FormProps["labelPosition"]>("right");

const onSubmit = () => {
  ErMessage.success("submit");
};
</script>

<template>
  <er-button-group size="small">
    <er-button
      @click="labelPosition = 'left'"
      :type="labelPosition === 'left' ? 'primary' : 'info'"
      >Left</er-button
    >
    <er-button
      @click="labelPosition = 'right'"
      :type="labelPosition === 'right' ? 'primary' : 'info'"
      >Right</er-button
    >
    <er-button
      @click="labelPosition = 'top'"
      :type="labelPosition === 'top' ? 'primary' : 'info'"
      >Top</er-button
    >
  </er-button-group>
  <div style="margin: 20px"></div>
  <er-form :model="form" :label-position="labelPosition">
    <er-form-item label="Activity name">
      <er-input v-model="form.name" />
    </er-form-item>
    <er-form-item label="Activity zone">
      <er-select
        v-model="form.region"
        placeholder="please select your zone"
        :options="options"
      />
    </er-form-item>
    <er-form-item label="Instant delivery">
      <er-switch v-model="form.delivery" />
    </er-form-item>
    <er-form-item label="Activity form">
      <er-input v-model="form.desc" type="textarea" />
    </er-form-item>
    <er-form-item>
      <er-button type="primary" @click="onSubmit">Create</er-button>
      <er-button>Cancel</er-button>
    </er-form-item>
  </er-form>
</template>

表单校验

通过 rules 属性可以设置表单项的校验规则。书写规则参考 async-validator

<script lang="ts" setup>
import { reactive, ref } from "vue";
import { ErMessage, type FormInstance } from "eric-ui";

const formRef = ref<FormInstance>();
const form = reactive({
  name: "",
  region: "",
  delivery: false,
  desc: "",
});

const options = ref([
  { value: "beijing", label: "Zone One" },
  { value: "shanghai", label: "Zone Two" },
]);

const rules = reactive({
  name: [
    { required: true, message: "请输入活动名称", trigger: "blur" },
    { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
  ],
  region: [{ required: true, message: "请选择活动区域", trigger: "change" }],
  desc: [{ required: true, message: "请填写活动形式", trigger: "blur" }],
});

const onSubmit = () => {
  formRef.value?.validate().then((valid) => {
    if (valid) {
      ErMessage.success("submit!");
    }
  });
};

const onReset = () => {
  formRef.value?.resetFields();
};
</script>

<template>
  <er-form ref="formRef" :model="form" :rules="rules">
    <er-form-item label="Activity name" prop="name">
      <er-input v-model="form.name" />
    </er-form-item>
    <er-form-item label="Activity zone" prop="region">
      <er-select
        v-model="form.region"
        placeholder="please select your zone"
        :options="options"
      />
    </er-form-item>
    <er-form-item label="Instant delivery" prop="delivery">
      <er-switch v-model="form.delivery" />
    </er-form-item>
    <er-form-item label="Activity form" prop="desc">
      <er-input v-model="form.desc" type="textarea" />
    </er-form-item>
    <er-form-item>
      <er-button type="primary" @click="onSubmit">Create</er-button>
      <er-button @click="onReset">Reset</er-button>
    </er-form-item>
  </er-form>
</template>

自定义校验规则

通过校验规则中的 validator 属性可以自定义校验规则。

<script lang="ts" setup>
import { reactive, ref } from "vue";
import { ErMessage, type FormInstance } from "eric-ui";

const formRef = ref<FormInstance>();
const form = reactive({
  name: "",
  password: "",
  passwordConfirm: "",
});

const rules: any = reactive({
  name: [
    { required: true, message: "请输入活动名称", trigger: "blur" },
    { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
  ],
  password: [{ required: true, trigger: "blur", message: "请输入密码" }],
  passwordConfirm: [
    {
      required: true,
      trigger: "blur",
      message: "请再次输入密码",
    },
    {
      validator: (_: typeof rules, value: string) => value === form.password,
      trigger: "blur",
      message: "两个密码必须相同",
    },
  ],
});

const onSubmit = async (instance?: FormInstance) => {
  const valid = await instance?.validate();
  if (!valid) return;
  ErMessage.success("submit!");
};

const onReset = () => {
  formRef.value?.resetFields();
};
</script>

<template>
  <er-form
    ref="formRef"
    :model="form"
    :rules="rules"
    label-position="top"
    @submit.prevent="onSubmit(formRef)"
  >
    <er-form-item label="Activity name" prop="name">
      <er-input v-model="form.name" />
    </er-form-item>
    <er-form-item label="Password" prop="password">
      <er-input v-model="form.password" type="password" />
    </er-form-item>
    <er-form-item label="Password Confirm" prop="passwordConfirm">
      <er-input v-model="form.passwordConfirm" type="password" />
    </er-form-item>
    <er-form-item>
      <er-button type="primary" native-type="submit">Create</er-button>
      <er-button @click="onReset">Reset</er-button>
    </er-form-item>
  </er-form>
</template>

Form API

Props

NameDescriptionTypeDefault
model表单数据Record<string, any>-
rules校验规则FormRules-
disabled是否禁用表单booleanfalse
label-position标签位置enum- 'left' | 'top'| right'right
label-width标签宽度number-
label-suffix标签后缀string-
show-message是否显示提示booleantrue
hide-required-asterisk是否隐藏必填符号booleanfalse
required-asterisk-position必填符号位置enum-'left' | 'right'right

Events

NameDescriptionType
validate验证表单项校验后触发(prop: FormItemProps, isValid: boolean, message: string ) => void

Slots

NameDescriptionSub Component
default默认插槽FormItem

Expose

NameDescriptionType
validate校验表单项() => Promise<boolean>
validateField校验指定表单项(props?: string[],callback?:(isValid:boolean,invalidFields?: ValidateFieldsError)) => Promise<boolean>
resetFields重置表单项(props?: string[]) => void
clearValidate清除校验状态(props?: string[]) => void

FormItem API

Props

NameDescriptionTypeDefault
prop表单域 model 字段string-
label标签文本string-
label-width标签宽度,例如 '50px'string|number-
disabled是否禁用表单域booleanfalse
required是否必填,如不设置,则会根据校验规则自动生成booleanfalse
show-message是否显示校验错误信息booleantrue
error错误提示文案,如不设置,则会从校验规则的 message 属性中获取string-
rules校验规则FormItemRule[]-

Slots

NameDescriptionType
default默认插槽-
labellabel 插槽{label:string}
error错误提示文案插槽{error:string}

Expose

NameDescriptionType
validateStatus校验状态Ref<ValidateStatus> - 'success' | 'error' | 'validating' | 'init'
validateMessage校验信息Ref<string>
validate校验表单项(trigger: string,callback?: (valid: boolean,invalidFields?: ValidateFieldsError) => void) => Promise<boolean>
resetField重置表单项() => void
clearValidate清除校验结果() => void