CollapseForm 折叠表单
基于ZForm组件和ElCollapse组件封装。
常规使用
表单类型type传入collapse,column项中配置children(表单项),可以实现可折叠表单。
activeCollapse绑定展开的折叠项label,如不想绑定label,请在column项中配置字段key。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const activeCollapse = ref(['文本', '标题'])
const formRef = ref()
const formData = ref({
name: '',
gender: '',
time: [],
})
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
const columns = [
{
label: '文本',
children: [
{
component: 'input',
field: 'name',
modifier: 'trim',
label: '姓名',
onInput: (val: string) => {
console.log(val, 'input event')
},
onChange: (val: string) => {
console.log(val, 'change event')
},
rules: {
required: true,
},
},
],
},
{
label: '标题',
children: [
{
component: 'select',
field: 'gender',
label: '性别',
md: 12,
onChange: (val: string) => {
console.log(val, 'change event')
},
onFocus: () => {
console.log('focus event')
},
},
{
component: 'el-date-picker',
field: 'time',
label: '出生日期',
md: 12,
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
onChange: (val: string) => {
console.log(val, 'change event')
},
},
],
},
{
slot: 'operate',
},
]
function reset() {
formRef.value.resetFields()
}
function submit() {
formRef.value.validate((valid: boolean) => {
if (valid) {
ElMessage.success('成功')
console.log(formData.value, 'config.formData')
}
else {
console.log('error submit!!')
return false
}
})
}
</script>
<template>
<z-form
ref="formRef"
v-model="formData"
v-model:activeCollapse="activeCollapse"
:options="options"
:columns="columns"
label-width="80px"
size="default"
type="collapse"
>
<template #operate>
<div class="mt-4 w-full flex">
<el-button class="w-full" @click="reset">
重置
</el-button>
<el-button class="w-full" type="primary" @click="submit">
提交
</el-button>
</div>
</template>
</z-form>
</template>标题
默认column项的label字段为折叠项的name,如果label为函数或不想将label作为折叠项name,请额外传入key字段。支持slot插槽自定义标题。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, ref } from 'vue'
import { ElMessage } from 'element-plus'
const activeCollapse = ref(['bbb', 'labelSlot'])
const formRef = ref()
const formData = ref({
name: '',
gender: '',
time: [],
})
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
const columns = [
{
label: () => h('span', {}, '文本a'),
key: 'bbb',
children: [
{
component: 'input',
field: 'name',
modifier: 'trim',
label: '姓名',
onInput: (val: string) => {
console.log(val, 'input event')
},
onChange: (val: string) => {
console.log(val, 'change event')
},
rules: {
required: true,
},
},
],
},
{
label: 'labelSlot',
children: [
{
component: 'select',
field: 'gender',
label: '性别',
md: 12,
onChange: (val: string) => {
console.log(val, 'change event')
},
onFocus: () => {
console.log('focus event')
},
},
{
component: 'el-date-picker',
field: 'time',
label: '出生日期',
md: 12,
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
onChange: (val: string) => {
console.log(val, 'change event')
},
},
],
},
{
slot: 'operate',
},
]
function reset() {
formRef.value.resetFields()
}
function submit() {
formRef.value.validate((valid: boolean) => {
if (valid) {
ElMessage.success('成功')
console.log(formData.value, 'config.formData')
}
else {
console.log('error submit!!')
return false
}
})
}
</script>
<template>
<z-form
ref="formRef"
v-model="formData"
v-model:activeCollapse="activeCollapse"
:options="options"
:columns="columns"
label-width="80px"
size="default"
type="collapse"
>
<template #labelSlot>
<span>label自定义</span>
</template>
<template #operate>
<div class="mt-4 w-full flex">
<el-button class="w-full" @click="reset">
重置
</el-button>
<el-button class="w-full" type="primary" @click="submit">
提交
</el-button>
</div>
</template>
</z-form>
</template>折叠属性
accordion属性直接传入ZForm组件。disabled属性传入column项中,可以禁用折叠项。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const activeCollapse = ref('文本')
const formRef = ref()
const formData = ref({
name: '',
gender: '',
time: [],
})
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
const columns = [
{
label: '文本',
children: [
{
component: 'input',
field: 'name',
modifier: 'trim',
label: '姓名',
onInput: (val: string) => {
console.log(val, 'input event')
},
onChange: (val: string) => {
console.log(val, 'change event')
},
rules: {
required: true,
},
},
],
},
{
label: '标题',
children: [
{
component: 'select',
field: 'gender',
label: '性别',
md: 12,
onChange: (val: string) => {
console.log(val, 'change event')
},
onFocus: () => {
console.log('focus event')
},
},
{
component: 'el-date-picker',
field: 'time',
label: '出生日期',
md: 12,
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
onChange: (val: string) => {
console.log(val, 'change event')
},
},
],
},
{
label: '禁用',
disabled: true,
children: [
{
component: 'input',
field: 'disabled',
label: '禁用',
},
],
},
{
slot: 'operate',
},
]
function reset() {
formRef.value.resetFields()
}
function submit() {
formRef.value.validate((valid: boolean) => {
if (valid) {
ElMessage.success('成功')
console.log(formData.value, 'config.formData')
}
else {
console.log('error submit!!')
return false
}
})
}
</script>
<template>
<z-form
ref="formRef"
v-model="formData"
v-model:activeCollapse="activeCollapse"
:options="options"
:columns="columns"
label-width="80px"
size="default"
type="collapse"
accordion
>
<template #operate>
<div class="mt-4 w-full flex">
<el-button class="w-full" @click="reset">
重置
</el-button>
<el-button class="w-full" type="primary" @click="submit">
提交
</el-button>
</div>
</template>
</z-form>
</template>自定义内容
当ZForm组件type属性为collapse时,column项可配置slot或render自定义折叠内容。
TIP
column项传入children字段(不管数组有没有长度),都会渲染ElCollapse的折叠项
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import { ElInput, ElMessage } from 'element-plus'
const activeCollapse = ref(['文本', '标题'])
const formRef = ref()
const formData = ref({
name: '',
gender: '',
address: '',
input: '',
time: [],
})
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
const columns = [
{
label: '文本',
children: [
{
component: 'input',
field: 'name',
modifier: 'trim',
label: '姓名',
required: true,
},
],
},
{
label: '标题',
render: () => h('span', 'custom content'),
children: [],
},
{
label: '地址',
slot: 'addressSlot',
},
{
label: '输入框',
slot: 'input',
required: true,
message: '请输入文案',
},
{
slot: 'operate',
},
]
function reset() {
formRef.value.resetFields()
}
function submit() {
formRef.value.validate((valid: boolean) => {
if (valid) {
ElMessage.success('成功')
console.log(formData.value, 'config.formData')
}
else {
console.log('error submit!!')
return false
}
})
}
</script>
<template>
<z-form
ref="formRef"
v-model="formData"
v-model:activeCollapse="activeCollapse"
:options="options"
:columns="columns"
label-width="80px"
size="default"
type="collapse"
>
<template #addressSlot>
<div>自定义地址</div>
</template>
<template #input>
<ElInput v-model="formData.input" />
</template>
<template #operate>
<div class="mt-4 w-full flex">
<el-button class="w-full" @click="reset">
重置
</el-button>
<el-button class="w-full" type="primary" @click="submit">
提交
</el-button>
</div>
</template>
</z-form>
</template>折叠展开事件
collapse-change事件返回当前展开的折叠项label,直接绑定ZForm组件即可。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const activeCollapse = ref(['文本', '标题'])
const formRef = ref()
const formData = ref({
name: '',
gender: '',
time: [],
})
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
const columns = [
{
label: '文本',
children: [
{
component: 'input',
field: 'name',
modifier: 'trim',
label: '姓名',
onInput: (val: string) => {
console.log(val, 'input event')
},
onChange: (val: string) => {
console.log(val, 'change event')
},
rules: {
required: true,
},
},
],
},
{
label: '标题',
children: [
{
component: 'select',
field: 'gender',
label: '性别',
md: 12,
onChange: (val: string) => {
console.log(val, 'change event')
},
onFocus: () => {
console.log('focus event')
},
},
{
component: 'el-date-picker',
field: 'time',
label: '出生日期',
md: 12,
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
onChange: (val: string) => {
console.log(val, 'change event')
},
},
],
},
{
slot: 'operate',
},
]
function reset() {
formRef.value.resetFields()
}
function submit() {
formRef.value.validate((valid: boolean) => {
if (valid) {
ElMessage.success('成功')
console.log(formData.value, 'config.formData')
}
else {
console.log('error submit!!')
return false
}
})
}
function handleCollapseChange(val: string) {
console.log(val, 'val')
}
</script>
<template>
<z-form
ref="formRef"
v-model="formData"
v-model:activeCollapse="activeCollapse"
:options="options"
:columns="columns"
label-width="80px"
size="default"
type="collapse"
@collapse-change="handleCollapseChange"
>
<template #operate>
<div class="mt-4 w-full flex">
<el-button class="w-full" @click="reset">
重置
</el-button>
<el-button class="w-full" type="primary" @click="submit">
提交
</el-button>
</div>
</template>
</z-form>
</template>折叠表单属性
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model:activeCollapse | 展开的collapse项(type为collapse生效) | array / string | — |
| accordion | 手风琴模式 | boolean | false |
事件
| 事件名 | 说明 | 类型 |
|---|---|---|
| update:modelValue | 表单项数据 | Function |
| update:activeCollapse | 折叠表单的展开项 | Function |
| collapse-change | 折叠表单折叠项改变时触发 | Function |