Skip to content
On this page

adv-form 表单

封装于 el-form,在不破坏其原有功能基础上,利用 JSON Schema 来生成表单的工具。

安装

shell
# 选择一个你喜欢的包管理器

# NPM
$ npm install @advanced-elements/form --save
# Yarn
$ yarn add @advanced-elements/form
# pnpm
$ pnpm add @advanced-elements/form

代码示例

input1
input2
input1关联:input1
-
select1
Option1
select2
select3
radio1
radio2
0
checkbox1
0
checkbox2
number1
colorPicker1
colorPicker2
#A30F0F
treeSelect1
rate1
rate2
3 points
switch2
switchfalse
switch1
test1-custom
timePicker1
timePicker2
00:32:42
datePicker2
测试form1ss
form1-input1
form1-input2
-
form1-input3
timePicker1
formlistss
formlist-formss
form1-input1
form1-input2

查看代码
vue
<template>
  <AdvForm
    ref="formRef"
    v-model:model="modelForm"
    :fields="list"
    :form-props="{
      rules,
      labelWidth: 'auto',
      inline: true,
    }"
    :row-props="{
      gutter: 20,
    }"
    :on-submit="onSubmit"
    :has-reset="true"
    :submit-prop="submitProp"
    :components-maps="maps"
  />
<ElButton @click="handleSubmit">外部提交</ElButton>
</template>

<script setup>
import { defineComponent, reactive, ref } from 'vue'
const formRef = ref()
const submitProp = ref({
  submitText: 'submit',
})
const maps = {}
const request = (params) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve([
        {
          value: 'Option1',
          label: 'Option1',
        },
        {
          value: 'Option2',
          label: params ? params.select3 : 'Option2',
        },
      ])
    }, 3000)
  })
}
const list = ref([
  {
    prop: 'input1',
    type: 'input',
    formItemProps: {
      label: 'input1',
      // labelWidth: 'auto',
    },
    componentProps: {
      showPassword: true,
    },
    colProps: {
      span: 12,
    },
  },
  {
    prop: 'input2',
    type: 'input',
    formItemProps: {
      label: 'input2',
    },
    componentProps: {
      showPassword: true,
    },
    condFunc: () => {
      return modelForm.value.input1.length > 5
    },
    colProps: {
      span: 12,
    },
  },
  {
    prop: 'input3',
    type: 'input',
    formItemProps: {
      label: 'input3',
      labelFunc: () => {
        return `input1关联:${modelForm.value.input1}`
      },
      advReadonly: true,
    },
    componentProps: {},
    colProps: {
      span: 3,
    },
  },
  {
    prop: 'select1',
    type: 'select',
    formItemProps: {
      label: 'select1',
      advReadonly: true,
    },
    componentProps: {
      options: [
        {
          value: 'Option1',
          label: 'Option1',
        },
        {
          value: 'Option2',
          label: 'Option2',
        },
      ],
    },
  },
  {
    prop: 'select2',
    type: 'select',
    formItemProps: {
      label: 'select2',
      dependenciesRules: () => {
        if (modelForm.value.input1) {
          return {
            required: true,
            message: 'Please select Activity zone',
            trigger: 'change',
          }
        } else {
          return {}
        }
      },
    },
    componentProps: {
      request,
    },
    dependencies: ['select3', 'form1/input1'],
  },
  {
    prop: 'select3',
    type: 'select',
    formItemProps: {
      label: 'select3',
    },
    componentProps: {
      groups: [
        {
          label: 'Popular cities',
          options: [
            {
              value: 'Shanghai',
              label: 'Shanghai',
            },
            {
              value: 'Beijing',
              label: 'Beijing',
            },
          ],
        },
        {
          label: 'City name',
          options: [
            {
              value: 'Chengdu',
              label: 'Chengdu',
            },
            {
              value: 'Shenzhen',
              label: 'Shenzhen',
            },
          ],
        },
      ],
    },
  },
  {
    prop: 'radio1',
    type: 'radio',
    formItemProps: {
      label: 'radio1',
    },
    componentProps: {
      options: [
        {
          label: 'Shanghai',
        },
        {
          label: 'Beijing',
        },
      ],
    },
  },
  {
    prop: 'radio2',
    type: 'radio',
    formItemProps: {
      label: 'radio2',
    },
    componentProps: {
      request: (params) => {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve([
              {
                label: 'Shanghai',
              },
              {
                label: 'Beijing',
              },
            ])
          }, 3000)
        })
      },
    },
  },
  {
    prop: 'checkbox1',
    type: 'checkbox',
    formItemProps: {
      label: 'checkbox1',
    },
    componentProps: {
      request: (params) => {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve([
              {
                label: 'Shanghai',
              },
              {
                label: 'Beijing',
              },
            ])
          }, 3000)
        })
      },
    },
  },
  {
    prop: 'checkbox2',
    type: 'checkbox',
    formItemProps: {
      label: 'checkbox2',
    },
    componentProps: {
      options: [
        {
          label: 'Shanghai',
        },
        {
          label: 'Beijing',
        },
      ],
    },
  },
  {
    prop: 'number1',
    type: 'number',
    formItemProps: {
      label: 'number1',
    },
    componentProps: {},
  },
  {
    prop: 'colorPicker1',
    type: 'colorPicker',
    formItemProps: {
      label: 'colorPicker1',
    },
    componentProps: {},
  },
  {
    prop: 'colorPicker2',
    type: 'colorPicker',
    formItemProps: {
      label: 'colorPicker2',
      advReadonly: true,
    },
    componentProps: {},
  },
  {
    prop: 'treeSelect1',
    type: 'treeSelect',
    formItemProps: {
      label: 'treeSelect1',
    },
    componentProps: {
      data: [
        {
          value: '1',
          label: 'Level one 1',
          children: [
            {
              value: '1-1',
              label: 'Level two 1-1',
              children: [
                {
                  value: '1-1-1',
                  label: 'Level three 1-1-1',
                },
              ],
            },
          ],
        },
        {
          value: '2',
          label: 'Level one 2',
          children: [
            {
              value: '2-1',
              label: 'Level two 2-1',
              children: [
                {
                  value: '2-1-1',
                  label: 'Level three 2-1-1',
                },
              ],
            },
            {
              value: '2-2',
              label: 'Level two 2-2',
              children: [
                {
                  value: '2-2-1',
                  label: 'Level three 2-2-1',
                },
              ],
            },
          ],
        },
      ],
    },
  },
  {
    prop: 'rate1',
    type: 'rate',
    formItemProps: {
      label: 'rate1',
    },
    componentProps: {},
  },
  {
    prop: 'rate2',
    type: 'rate',
    formItemProps: {
      label: 'rate2',
      advReadonly: true,
    },
    componentProps: {
      showScore: true,
      scoreTemplate: '{value} points',
      texts: ['oops', 'disappointed', 'normal', 'good', 'great'],
    },
  },
  {
    prop: 'switch2',
    type: 'switch',
    formItemProps: {
      label: 'switch2',
    },
    componentProps: {
      activeText: 'switchtrue',
      inactiveText: 'switchfalse',
    },
  },
  {
    prop: 'switch1',
    type: 'switch',
    formItemProps: {
      label: 'switch1',
    },
    componentProps: {
      activeText: '',
      inactiveText: '',
    },
  },
  {
    prop: 'input5',
    type: 'test1',
    formItemProps: {
      label: 'test1-custom',
    },
    componentProps: {
      showPassword: true,
    },
  },
  {
    prop: 'timePicker1',
    type: 'timePicker',
    formItemProps: {
      label: 'timePicker1',
    },
    componentProps: {
      isRange: true,
    },
  },
  {
    prop: 'timePicker2',
    type: 'timePicker',
    formItemProps: {
      label: 'timePicker2',
      advReadonly: true,
    },
    componentProps: {},
  },
  {
    prop: 'datePicker2',
    type: 'datePicker',
    formItemProps: {
      label: 'datePicker2',
    },
    componentProps: {
      type: 'month',
    },
  },
  {
    type: 'form',
    prop: 'form1',
    formProps: {
      rules: {
        input1: [
          {
            required: true,
            message: 'Please input input1',
            trigger: 'blur',
          },
        ],
      },
      label: '测试form1',
    },
    fields: [
      {
        prop: 'input1',
        type: 'input',
        colProps: {
          span: 6,
        },
        formItemProps: {
          label: 'form1-input1',
          labelWidth: 'auto',
        },
        componentProps: {
          showPassword: true,
        },
      },
      {
        prop: 'input2',
        type: 'input',
        formItemProps: {
          label: 'form1-input2',
          advReadonly: true,
          labelWidth: 'auto',
        },
        colProps: {
          span: 6,
        },
        componentProps: {
          showPassword: true,
        },
      },
      {
        prop: 'input3',
        type: 'input',
        formItemProps: {
          label: 'form1-input3',
        },
        componentProps: {
          showPassword: true,
        },
        condFunc: () => {
          return modelForm.value.input1.length > 5
        },
      },
      {
        prop: 'timePicker1',
        type: 'timePicker',
        formItemProps: {
          label: 'timePicker1',
        },
        componentProps: {
          isRange: true,
        },
      },
    ],
    hasReset: true,
  },
  {
    type: 'formList',
    prop: 'formList1',
    formProps: {
      rules: {
        input1: [
          {
            required: true,
            message: 'Please input input1',
            trigger: 'blur',
          },
        ],
      },
      hasReset: true,
      label: 'formlist',
    },
    fields: [
      {
        type: 'form',
        prop: 'form1',
        formProps: {
          rules: {
            input1: [
              {
                required: true,
                message: 'Please input input1',
                trigger: 'blur',
              },
            ],
          },
          label: 'formlist-form',
          hasReset: true,
        },
        fields: [
          {
            prop: 'input1',
            type: 'input',
            colProps: {
              span: 12,
            },
            formItemProps: {
              label: 'form1-input1',
              labelWidth: 'auto',
            },
            componentProps: {
              showPassword: true,
            },
          },
          {
            prop: 'input2',
            type: 'input',
            colProps: {
              span: 12,
            },
            formItemProps: {
              label: 'form1-input2',
              labelWidth: 'auto',
            },
            componentProps: {
              showPassword: true,
            },
          },
        ],
      },
    ],
  },
])
const modelForm = ref({
  input1: 'input1',
  input2: '',
  input3: 'input3',
  radio1: '',
  radio2: '',
  select1: 'Option1',
  select2: 'Option1',
  number: null,
  switch1: true,
  switch2: 'switchtrue',
  timePicker1: null,
  timePicker2: new Date(),
  datePicker2: null,
  checkbox1: [],
  checkbox2: [],
  rate1: null,
  rate2: 3,
  colorPicker1: null,
  colorPicker2: '#A30F0F',
  treeSelect1: null,
  form1: {
    input1: 'form1input1',
    input2: '',
    input3: 'form1input3',
    timePicker1: null,
  },
  formList1: [
    {
      input1: '',
      input2: '',
    },
  ],
})
const rules = reactive({
  input1: [
    {
      required: true,
      message: 'Please input Activity name',
      trigger: 'blur',
    },
    { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
  ],
  radio21: [
    { required: true, message: 'Please input radio2', trigger: 'change' },
  ],
})
const handleSubmit = async () => {
  if (formRef.value) {
    const value = await formRef.value.validate()
    if (value === true) {
      alert('外部提交成功')
    }
  }
}

const onSubmit = () => {
  return (
    new Promise((resolve) => {
      setTimeout(() => {
        modelForm.value.select1 = 'Option2'
        alert('内部提交成功')
        resolve(true)
      }, 600)
    })
  )
}
</script>

其他

关于样式

如果项目是自动导入 element-plus,需要手动引入相关样式

普通使用

javascript
import '@advanced-elements/form/es/index.css'

配合 namespace 使用

javascript
import '@advanced-elements/form/style/index.scss'