123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- <template>
- <div class="step-container">
- <!-- 横向滚动步骤条 -->
- <div class="steps-wrapper" ref="stepsContainer">
- <el-steps :active="currentStep" finish-status="success" class="dynamic-steps" simple>
- <el-step
- v-for="(step, index) in totalSteps"
- :key="index"
- :title="`步骤 ${index + 1}`"
- :ref="setStepRef"
- />
- </el-steps>
- </div>
- <!-- 通用表单 -->
- <div class="form-wrapper">
- <el-form :model="formData[currentStep]" :rules="formRules" ref="formRef" label-width="120px">
- <el-form-item label="姓名" prop="name">
- <el-input v-model="formData[currentStep].name" />
- </el-form-item>
- <el-form-item label="邮箱" prop="email">
- <el-input v-model="formData[currentStep].email" />
- </el-form-item>
- <el-form-item label="验证码" prop="code">
- <el-input v-model="formData[currentStep].code" />
- </el-form-item>
- </el-form>
- </div>
- <!-- 导航按钮 -->
- <div class="action-buttons">
- <el-button @click="prevStep" :disabled="currentStep === 0"> 上一步 </el-button>
- <span class="step-indicator"> 当前步骤:{{ currentStep + 1 }}/{{ totalSteps }} </span>
- <el-button type="primary" @click="nextStep" :disabled="currentStep === totalSteps - 1">
- {{ isLastStep ? '完成' : '下一步' }}
- </el-button>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { computed, onMounted, ref } from 'vue'
- import { ElMessage } from 'element-plus'
- import {any} from "vue-types";
- const totalSteps = 30 // 总步骤数
- const currentStep = ref(0) // 当前步骤索引
- const stepsContainer = ref(null) // 步骤容器引用
- const stepElements = [] // 步骤元素集合
- const formRef = ref(null) // 表单引用
- defineOptions({ name: 'OrderComponent' })
- const props = defineProps<{ data: any }>(); // 搜索参数
- // 初始化表单数据
- const formData = ref(
- Array.from({ length: totalSteps }, () => ({
- name: '',
- email: '',
- code: ''
- }))
- )
- // 表单验证规则
- const formRules = {
- name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
- email: [
- { required: true, message: '请输入邮箱', trigger: 'blur' },
- { type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
- ],
- code: [
- { required: true, message: '请输入验证码', trigger: 'blur' },
- { pattern: /^\d{6}$/, message: '请输入6位数字验证码' }
- ]
- }
- // 步骤元素引用收集
- const setStepRef = (el) => {
- if (el) stepElements.push(el)
- }
- // 自动滚动到当前步骤
- const scrollToCurrentStep = () => {
- if (!stepsContainer.value) return
- const container = stepsContainer.value
- const currentEl = stepElements[currentStep.value]?.$el
- if (currentEl) {
- const containerWidth = container.offsetWidth
- const stepLeft = currentEl.offsetLeft
- const stepWidth = currentEl.offsetWidth
- container.scrollTo({
- left: stepLeft - containerWidth / 2 + stepWidth / 2,
- behavior: 'smooth'
- })
- }
- }
- // 导航逻辑
- const prevStep = () => {
- if (currentStep.value > 0) currentStep.value--
- }
- const nextStep = async () => {
- try {
- // 验证当前表单
- await formRef.value.validate()
- if (currentStep.value < totalSteps - 1) {
- currentStep.value++
- } else {
- ElMessage.success('所有步骤已完成!')
- console.log('最终提交数据:', formData.value)
- }
- } catch (error) {
- ElMessage.error('请正确填写当前步骤表单')
- }
- }
- // 计算属性
- const isLastStep = computed(() => currentStep.value === totalSteps - 1)
- // 生命周期钩子
- onMounted(() => {
- // 初始化时滚动到第一个步骤
- scrollToCurrentStep()
- debugger
- })
- </script>
- <style scoped>
- .step-container {
- max-width: 100%;
- //margin: 20px auto;
- //padding: 20px;
- }
- .steps-wrapper {
- overflow-x: auto;
- margin-bottom: 30px;
- padding: 10px 0;
- }
- .dynamic-steps {
- width: max-content;
- min-width: 100%;
- }
- .el-step {
- flex-shrink: 0;
- min-width: 120px;
- }
- .form-wrapper {
- border: 1px solid #ebeef5;
- border-radius: 4px;
- padding: 20px;
- margin: 20px 0;
- }
- .action-buttons {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .step-indicator {
- color: #666;
- font-size: 14px;
- }
- </style>
|