Skip to content

StepForm 组表单

基于ZForm组件和ElStep组件封装。

步骤条表单

表单类型type传入stepcolumns中配置children(表单项),可以实现步骤条表单。当前步骤通过activeStep双向绑定。

column中配置labeldescriptioniconstatus,可以配置步骤条文案、描述、图标和状态。

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, ref } from 'vue'

const activeStep = ref(0)
const formRef = ref()
const formData = ref({
  name: '',
  gender: '',
  time: [],
})

const options = {
  gender: [
    { label: '男', value: '1' },
    { label: '女', value: '2' },
  ],
}

const columns = [
  {
    label: '第一步',
    description: '描述内容',
    children: [
      {
        component: 'input',
        field: 'name',
        modifier: 'trim',
        label: '姓名',
        tooltip: '姓名',
        extra: '姓名',
        onInput: (val: string) => {
          console.log(val, 'input event')
        },
        onChange: (val: string) => {
          console.log(val, 'change event')
        },
        required: true,
      },
    ],
  },
  {
    label: () => h('span', {}, '第二部'),
    description: () => h('span', {}, '描述内容'),
    children: [
      {
        component: 'select',
        field: 'gender',
        label: '性别',
        onChange: (val: string) => {
          console.log(val, 'change event')
        },
        onFocus: () => {
          console.log('focus event')
        },
        rules: {
          required: true,
        },
      },
      {
        component: 'el-date-picker',
        field: 'time',
        label: '出生日期',
        fieldProps: {
          type: 'daterange',
          startPlaceholder: '开始日期',
          endPlaceholder: '结束日期',
        },
        onChange: (val: string[]) => {
          console.log(val, 'change event')
        },
      },
    ],
  },
]

// function reset() {
//   formRef.value.resetFields()
// }

function submit() {
  console.log(formData.value, 'success')
}
</script>

<template>
  <z-form
    ref="formRef"
    v-model="formData"
    v-model:activeStep="activeStep"
    :options="options"
    :columns="columns"
    label-width="80px"
    size="default"
    type="step"
    @submit="submit"
  />
</template>

Step属性

el-step组件属性,如:process-statusfinish-statusalign-center等,直接通过z-form传入。

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, ref } from 'vue'

const activeStep = ref(0)
const formRef = ref()
const formData = ref({
  name: '',
  gender: '',
  time: [],
})

const options = {
  gender: [
    { label: '男', value: '1' },
    { label: '女', value: '2' },
  ],
}

const columns = [
  {
    label: '第一步',
    description: '描述内容',
    children: [
      {
        component: 'input',
        field: 'name',
        modifier: 'trim',
        label: '姓名',
        required: true,
      },
    ],
  },
  {
    label: () => h('span', {}, '第二部'),
    description: () => h('span', {}, '描述内容'),
    children: [
      {
        component: 'select',
        field: 'gender',
        label: '性别',
      },
      {
        component: 'el-date-picker',
        field: 'time',
        label: '出生日期',
        fieldProps: {
          type: 'daterange',
          startPlaceholder: '开始日期',
          endPlaceholder: '结束日期',
        },
      },
    ],
  },
]

// function reset() {
//   formRef.value.resetFields()
// }

function submit() {
  console.log(formData.value, 'success')
}
</script>

<template>
  <z-form
    ref="formRef"
    v-model="formData"
    v-model:activeStep="activeStep"
    :options="options"
    :columns="columns"
    label-width="80px"
    size="default"
    type="step"
    process-status="error"
    finish-status="success"
    @submit="submit"
  />
</template>

自定义

支持自定义column项的labeldescriptionicon内容。老规矩,支持传入render或带slot(无视大小写)的字符串。

<script lang="ts" setup>
import { h, ref } from 'vue'

const activeStep = ref(0)
const formRef = ref()
const formData = ref({
  name: '',
  gender: '',
  time: [],
})

const options = {
  gender: [
    { label: '男', value: '1' },
    { label: '女', value: '2' },
  ],
}

const columns = [
  {
    label: 'firstLabelSlot',
    description: 'firstDescSlot',
    children: [
      {
        component: 'input',
        field: 'name',
        label: '姓名',
        required: true,
      },
    ],
  },
  {
    label: () => h('span', {}, '第二部'),
    description: () => h('span', {}, '描述内容'),
    children: [
      {
        component: 'select',
        field: 'gender',
        label: '性别',
        required: true,
      },
      {
        component: 'el-date-picker',
        field: 'time',
        label: '出生日期',
        fieldProps: {
          type: 'daterange',
          startPlaceholder: '开始日期',
          endPlaceholder: '结束日期',
        },
      },
    ],
  },
]
</script>

<template>
  <z-form
    ref="formRef"
    v-model="formData"
    v-model:activeStep="activeStep"
    :options="options"
    :columns="columns"
    label-width="80px"
    size="default"
    type="step"
  >
    <template #firstLabelSlot>
      <span>custom label</span>
    </template>
    <template #firstDescSlot>
      <span>custom description</span>
    </template>
  </z-form>
</template>

配置footer插槽或者render函数可以自定义步骤条底部内容。

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'

const activeStep = ref(0)
const formRef = ref()
const formData = ref({
  name: '',
  gender: '',
  time: [],
})

const options = {
  gender: [
    { label: '男', value: '1' },
    { label: '女', value: '2' },
  ],
}

const columns = [
  {
    label: '第一步',
    description: '描述内容',
    children: [
      {
        component: 'input',
        field: 'name',
        modifier: 'trim',
        label: '姓名',
        required: true,
      },
    ],
  },
  {
    label: '第二部',
    description: '描述内容',
    children: [
      {
        component: 'select',
        field: 'gender',
        label: '性别',
        onChange: (val: string) => {
          console.log(val, 'change event')
        },
        onFocus: () => {
          console.log('focus event')
        },
        required: true,
      },
      {
        component: 'el-date-picker',
        field: 'time',
        label: '出生日期',
        fieldProps: {
          type: 'daterange',
          startPlaceholder: '开始日期',
          endPlaceholder: '结束日期',
        },
        onChange: (val: string[]) => {
          console.log(val, 'change event')
        },
      },
    ],
  },
]

function handlePrevious() {
  activeStep.value--
}

function handleNext() {
  formRef.value.validate((val: boolean) => {
    if (val)
      activeStep.value++
  })
}

function submit() {
  formRef.value.validate((val: boolean) => {
    if (val) {
      ElMessage.success('success')
      console.log(formData.value, 'success')
    }
  })
}
</script>

<template>
  <z-form
    ref="formRef" v-model="formData" v-model:activeStep="activeStep" :options="options" :columns="columns"
    label-width="80px" size="default" type="step"
  >
    <template #footer>
      <el-button :disabled="activeStep === 0" @click="handlePrevious">
        上一步
      </el-button>
      <el-button :disabled="activeStep === 1" @click="handleNext">
        下一步
      </el-button>
      <el-button v-if="activeStep === 1" @click="submit">
        提交
      </el-button>
    </template>
  </z-form>
</template>

step表单属性

属性名说明类型默认值
modelValue:activeStep当前步骤number0
process-status设置当前步骤的状态wait / process / finish / error / successprocess
finish-status设置结束步骤的状态wait / process / finish / error / successfinish
align-center居中对齐booleantrue

Released under the MIT License.