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
<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/audition/demo-apply/components/step1-form-content.vue';
import Step2FormContent from '@/views/audition/demo-apply/components/step2-form-content.vue';
import Step3FormContent from '@/views/audition/demo-apply/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="140" class="aside">
<Steps :current="currentStep" direction="vertical">
<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>