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 |