ProFormDialog 弹框表单
ProFormDialog 弹框表单组件是在 ProForm 超级表单 和 ProDialog 超级弹框 的基础上进行拓展,因此完全兼容这些组件的所有 Props 配置、Emit 事件、Slots 插槽。
基础用法
vue
<script lang="ts" setup>
import type { ElFormProps, FormColumn } from "@/components/pro/form";
import { ref, computed } from "vue";
import { ProFormDialog } from "@/components/pro/form-dialog";
const confirmLoading = ref(false);
const dialogVisible = ref(false);
const state = ref({ name: "名称" });
const elFormProps: Partial<ElFormProps> = {
rules: {
name: [{ required: true, message: "请输入名称" }],
tag: [{ required: true, message: "请输入标签" }],
},
};
const columns: FormColumn[] = [
{
label: "名称",
prop: "name",
tooltip: computed(() => (state.value.name as string) || "提示:复制名称"),
},
{
label: "状态",
prop: "status",
el: "el-select",
options: [
{ label: "未解决", value: "0" },
{ label: "已解决", value: "1" },
{ label: "解决中", value: "2" },
{ label: "失败", value: "3" },
],
},
{ label: "是否显示", prop: "switch", el: "el-switch" },
{
label: "城市",
prop: "city",
el: "el-cascader",
options: [
{
value: "0",
label: "陕西",
children: [
{
value: "0-0",
label: "西安",
children: [
{ value: "0-0-0", label: "新城区" },
{ value: "0-0-1", label: "高新区" },
{ value: "0-0-2", label: "灞桥区" },
],
},
],
},
{
value: "1",
label: "山西",
children: [
{
value: "1-0",
label: "太原",
children: [
{ value: "1-0-0", label: "小店区" },
{ value: "1-0-1", label: "古交市" },
{ value: "1-0-2", label: "万柏林区" },
],
},
],
},
],
},
{
label: "要求",
prop: "demand",
el: "el-checkbox",
options: [
{ label: "四六级", value: "0" },
{ label: "计算机二级证书", value: "1" },
{ label: "普通话证书", value: "2" },
],
},
{
label: "梦想",
prop: "gift",
el: "el-radio",
options: [
{
label: "诗",
value: "0",
},
{
label: "远方",
value: "1",
},
{
label: "美食",
value: "2",
},
],
},
{
label: "到期时间",
prop: "endTime",
el: "el-date-picker",
elProps: {
type: "datetimerange",
startPlaceholder: "请选择开始时间",
endPlaceholder: "请选择结束时间",
},
},
{
label: "说明",
prop: "desc",
el: "el-input",
elProps: {
type: "textarea",
maxlength: 10,
showWordLimit: true,
autosize: { minRows: 2, maxRows: 4 },
},
},
];
const handleSubmit = () => {
confirmLoading.value = true;
setTimeout(() => {
confirmLoading.value = false;
dialogVisible.value = false;
}, 2000);
};
</script>
<template>
<div>
<el-button @click="dialogVisible = true">打开弹窗表单</el-button>
<ProFormDialog
v-model:visible="dialogVisible"
v-model="state"
:dialog="{ title: '表单标题', confirmLoading, height: 600 }"
:form="{ elFormProps, columns }"
@confirm="handleSubmit"
/>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
隐藏源代码
自定义表单组件
使用 ProForm 的自定义表单组件插槽:render、jsx/tsx、slot。
vue
<script lang="tsx" setup>
import type { ElFormProps, FormColumn } from "@/components/pro/form";
import { ref, computed, h } from "vue";
import { ProFormDialog } from "@/components/pro/form-dialog";
import { ElInput } from "element-plus";
const confirmLoading = ref(false);
const dialogVisible = ref(false);
const state = ref<Record<string, any>>({ name: "我是一个 h 函数渲染的 input", tag: "我是一个 tsx 渲染的标签" });
const elFormProps: Partial<ElFormProps> = {
rules: {
name: [{ required: true, message: "请输入名称" }],
tag: [{ required: true, message: "请输入标签" }],
},
};
const columns: FormColumn[] = [
{
label: "名称",
prop: "name",
tooltip: computed(() => (state.value.name as string) || "提示:复制名称"),
render: () => {
return h(ElInput);
},
},
{
label: "状态",
prop: "status",
el: "el-select",
options: [
{ label: "未解决", value: "0" },
{ label: "已解决", value: "1" },
{ label: "解决中", value: "2" },
{ label: "失败", value: "3" },
],
},
{
label: "标签",
prop: "tag",
render: value => {
return <div style="color: green;">{value}</div>;
},
},
{ label: "是否显示", prop: "switch", el: "el-switch" },
{ label: "时间", prop: "time", el: "el-date-picker" },
{ label: "数量", prop: "number", el: "el-input-number", elProps: { precision: 2, step: 2 } },
];
const handleSubmit = () => {
confirmLoading.value = true;
setTimeout(() => {
confirmLoading.value = false;
dialogVisible.value = false;
}, 2000);
};
</script>
<template>
<div>
<el-button @click="dialogVisible = true">打开弹窗表单</el-button>
<ProFormDialog
v-model:visible="dialogVisible"
v-model="state"
:dialog="{ title: '表单标题', confirmLoading, height: 400 }"
:form="{ elFormProps, columns }"
@confirm="handleSubmit"
>
<template #status>
<el-input v-model="state.status" type="textarea" placeholder="自定义输入框插槽" />
</template>
</ProFormDialog>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
隐藏源代码
自定义表单 Label
使用 ProForm 的自定义表单 Label 插槽:render、jsx/tsx、slot。
vue
<script lang="tsx" setup>
import type { ElFormProps, FormColumn } from "@/components/pro/form";
import { ref, computed, h } from "vue";
import { ProFormDialog } from "@/components/pro/form-dialog";
const confirmLoading = ref(false);
const dialogVisible = ref(false);
const state = ref<Record<string, any>>({
name: "我的 Label 由 h 函数渲染",
tag: "我的 Label 由 tsx 渲染",
});
const elFormProps: Partial<ElFormProps> = {
rules: {
name: [{ required: true, message: "请输入名称" }],
tag: [{ required: true, message: "请输入标签" }],
},
};
const columns: FormColumn[] = [
{
label: "名称",
prop: "name",
tooltip: computed(() => (state.value.name as string) || "提示:复制名称"),
renderLabel: value => {
return h("div", {}, value as string);
},
},
{
label: "状态",
prop: "status",
el: "el-select",
options: [
{ label: "未解决", value: "0" },
{ label: "已解决", value: "1" },
{ label: "解决中", value: "2" },
{ label: "失败", value: "3" },
],
},
{
label: "标签",
prop: "tag",
renderLabel: label => {
return <div style="color: green;">{label}</div>;
},
},
{ label: "是否显示", prop: "switch", el: "el-switch" },
{ label: "时间", prop: "time", el: "el-date-picker" },
{ label: "数量", prop: "number", el: "el-input-number", elProps: { precision: 2, step: 2 } },
];
const handleSubmit = () => {
confirmLoading.value = true;
setTimeout(() => {
confirmLoading.value = false;
dialogVisible.value = false;
}, 2000);
};
</script>
<template>
<div>
<el-button @click="dialogVisible = true">打开弹窗表单</el-button>
<ProFormDialog
v-model:visible="dialogVisible"
v-model="state"
:dialog="{ title: '表单标题', confirmLoading, height: 400 }"
:form="{ elFormProps, columns }"
@confirm="handleSubmit"
>
<template #status-label="{ label }">
<span style="color: red">{{ label }}</span>
</template>
</ProFormDialog>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
隐藏源代码
自定义底部
ProFormDialog 支持 ProForm 和 ProDialog 两个组件的底部插槽,默认情况下开启 ProDialog 的底部插槽,关闭 ProDialog 的底部插槽。
通过 dialog.showFooter 配置 false 来关闭 ProDialog 的底部插槽,并通过 form.showFooter 配置 true 来打开 ProForm 的底部插槽。
vue
<script lang="ts" setup>
import type { ElFormProps, FormColumn } from "@/components/pro/form";
import { ref, computed } from "vue";
import { ProFormDialog } from "@/components/pro/form-dialog";
const dialogVisible1 = ref(false);
const dialogVisible2 = ref(false);
const state = ref({ name: "名称" });
const elFormProps: Partial<ElFormProps> = {
rules: {
name: [{ required: true, message: "请输入名称" }],
tag: [{ required: true, message: "请输入标签" }],
},
};
const columns: FormColumn[] = [
{
label: "名称",
prop: "name",
tooltip: computed(() => (state.value.name as string) || "提示:复制名称"),
},
{
label: "状态",
prop: "status",
el: "el-select",
options: [
{ label: "未解决", value: "0" },
{ label: "已解决", value: "1" },
{ label: "解决中", value: "2" },
{ label: "失败", value: "3" },
],
},
{ label: "是否显示", prop: "switch", el: "el-switch" },
{
label: "城市",
prop: "city",
el: "el-cascader",
options: [
{
value: "0",
label: "陕西",
children: [
{
value: "0-0",
label: "西安",
children: [
{ value: "0-0-0", label: "新城区" },
{ value: "0-0-1", label: "高新区" },
{ value: "0-0-2", label: "灞桥区" },
],
},
],
},
{
value: "1",
label: "山西",
children: [
{
value: "1-0",
label: "太原",
children: [
{ value: "1-0-0", label: "小店区" },
{ value: "1-0-1", label: "古交市" },
{ value: "1-0-2", label: "万柏林区" },
],
},
],
},
],
},
{
label: "要求",
prop: "demand",
el: "el-checkbox",
options: [
{ label: "四六级", value: "0" },
{ label: "计算机二级证书", value: "1" },
{ label: "普通话证书", value: "2" },
],
},
{
label: "梦想",
prop: "gift",
el: "el-radio",
options: [
{
label: "诗",
value: "0",
},
{
label: "远方",
value: "1",
},
{
label: "美食",
value: "2",
},
],
},
{
label: "到期时间",
prop: "endTime",
el: "el-date-picker",
elProps: {
type: "datetimerange",
startPlaceholder: "请选择开始时间",
endPlaceholder: "请选择结束时间",
},
},
{
label: "说明",
prop: "desc",
el: "el-input",
elProps: {
type: "textarea",
maxlength: 10,
showWordLimit: true,
autosize: { minRows: 2, maxRows: 4 },
},
},
];
const handleAllConfirm = async (handleSubmit: () => Promise<boolean>) => {
const isPass = await handleSubmit();
isPass && (dialogVisible2.value = false);
};
</script>
<template>
<div>
<el-button @click="dialogVisible1 = true">打开弹窗表单(自定义弹窗底部插槽)</el-button>
<ProFormDialog
v-model:visible="dialogVisible1"
v-model="state"
:dialog="{ title: '表单标题', height: 450 }"
:form="{ elFormProps, columns }"
>
<template #dialog-footer="{ handleConfirm, handleCancel }">
<div style="margin: 0 auto">
<el-button type="info" @click="handleCancel">返回</el-button>
<el-button type="primary" @click="handleConfirm">通过</el-button>
<el-button type="warning" @click="handleCancel">重置</el-button>
<el-button type="danger" @click="handleCancel">驳回</el-button>
</div>
</template>
</ProFormDialog>
<el-button @click="dialogVisible2 = true">打开弹窗表单(自定义表单底部插槽)</el-button>
<ProFormDialog
v-model:visible="dialogVisible2"
v-model="state"
:dialog="{ title: '表单标题', showFooter: false, height: 500 }"
:form="{ elFormProps, columns, showFooter: true }"
>
<template #form-footer="{ handleSubmit, handleReset }">
<el-button type="primary" @click="handleAllConfirm(handleSubmit)">提交</el-button>
<el-button type="warning" @click="handleReset">重置</el-button>
<el-button type="danger" @click="handleReset">返回</el-button>
</template>
</ProFormDialog>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
隐藏源代码
如果使用的是组件,且只想额外添加底部按钮,可以通过如下插槽进行拓展:
- 使用
ProDialog底部插槽则是dialog-footer-before和dialog-footer-after - 使用
ProForm底部插槽则是form-footer-before和form-footer-after
Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| model-value / v-model | 表单绑定值 | object | |
| dialog | ProDialog 的 Props | object ProDialog | |
| form | ProForm 的 Props | object ProForm |
Event
| 名称 | 说明 | 类型 |
|---|---|---|
| change | 表单值改变事件 | function |
| confirm | 确认按钮点击事件 | function |
| cancel | 确认按钮点击事件 | function |
Slots
| 插槽名 | 说明 | 作用域插槽参数 |
|---|---|---|
| dialog-footer-before | ProDialog 的 footer-before 插槽 | |
| dialog-footer | ProDialog 的 footer 插槽 | |
| dialog-footer-after | ProDialog 的 footer-after 插槽 | |
| form-footer-before | ProForm 的 footer-before 插槽 | |
| form-footer | ProForm 的 footer 插槽 | |
| form-footer-after | ProForm 的 footer-after 插槽 | |
| ... | 其他扩展属性,支持所有 ProForm Slots 和 ProDialog Slots | ... |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| proFormInstance | ProForm 实例 | object |
| handleConfirm | 确认按钮点击事件 | function |
| handleCancel | 取消按钮点击事件 | function |
| open | 打开弹窗 | function |
| close | 关闭弹窗 | function |