form-content.vue
3 KB
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
<script setup lang="ts">
import { useSelectionStore } from "@/store";
import {
Layout,
LayoutSider,
LayoutContent,
LayoutFooter,
Step,
Steps,
Space,
Divider,
Link
} from "@arco-design/web-vue";
import Step1FormContent from "@/views/demo/components/step1-form-content.vue";
import Step2FormContent from "@/views/demo/components/step2-form-content.vue";
import Step3FormContent from "@/views/demo/components/step3-form-content.vue";
import IconButton from "@/components/icon-button/index.vue";
import { AnyObject } from "@/types/global";
import useLoading from "@/hooks/loading";
import { computed, markRaw, ref } from "vue";
import { cloneDeep } from "lodash";
const props = defineProps<{
initValue: AnyObject;
filterProject?: (value: unknown) => boolean;
onSubmit: (data: AnyObject) => Promise<any>;
}>();
const { loading, setLoading } = useLoading(false);
const formRef = ref();
const formValue = ref({ ...cloneDeep(props.initValue) });
const stepItems = [
{ value: 1, label: "基本信息", template: markRaw(Step1FormContent) },
{ value: 2, label: "补充信息", template: markRaw(Step2FormContent) },
{ value: 3, label: "上传文件", template: markRaw(Step3FormContent) }
];
const currentStep = ref(1);
const currentContent = computed(() => stepItems.find((item) => item.value === currentStep.value)?.template);
const nextBtnLabel = computed(() => (currentStep.value === 3 ? "提交" : "下一步"));
const onPrev = (): void => {
currentStep.value = Math.max(1, currentStep.value - 1);
};
const onNext = () => {
formRef.value.onValid(async () => {
if (currentStep.value === stepItems.length) {
setLoading(true);
props.onSubmit(formValue.value).finally(() => setLoading(false));
}
currentStep.value = Math.min(stepItems.length, currentStep.value + 1);
});
};
</script>
<template>
<Layout>
<Layout has-sider>
<LayoutSider :width="120" class="aside">
<Steps :current="currentStep" direction="vertical" :small="true">
<Step v-for="item in stepItems" :key="item.value">{{ item.label }}</Step>
</Steps>
</LayoutSider>
<LayoutContent class="main">
<component :is="currentContent" ref="formRef" v-model="formValue" v-model:loading="loading"
:filter-project="filterProject" />
</LayoutContent>
</Layout>
<LayoutFooter>
<Divider style="margin-top: 8px; margin-bottom: 20px" />
<Link :href="useSelectionStore().lyricTool" :hoverable="false" class="link-hover" icon>歌词制作工具</Link>
<Space style="float: right">
<IconButton v-show="currentStep !== 1" icon="left" label="上一步" @click="onPrev" />
<IconButton icon="right" icon-align="right" :loading="loading" :label="nextBtnLabel" @click="onNext" />
</Space>
</LayoutFooter>
</Layout>
</template>
<style scoped lang="less">
.aside {
box-shadow: unset !important;
border-right: 1px solid var(--color-border);
margin-right: 20px;
background-color: transparent;
}
.main {
min-width: 640px;
}
</style>