You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Vue.js实现幻灯片式调查问卷?求入门指导

用Vue.js实现问卷幻灯片切换的分步指南

嘿,我来帮你理清楚怎么用Vue.js实现这个问卷的幻灯片切换功能,不用慌,一步步拆解下来其实很清晰!

1. 先规划问卷的数据结构

首先你得把每个问卷步骤的内容结构化,用一个数组来存储所有步骤的信息,比如每个步骤包含标题、问题列表、问题类型这些。举个例子:

const surveySteps = [
  {
    id: 1,
    title: "第一步:基本信息",
    questions: [
      { type: "text", label: "你的姓名", name: "fullName", required: true },
      { type: "select", label: "你的年龄区间", name: "ageRange", options: ["18-25", "26-35", "36-45", "45+"] }
    ]
  },
  {
    id: 2,
    title: "第二步:健康习惯",
    questions: [
      { type: "radio", label: "你每周运动几次?", name: "exerciseFreq", options: ["0次", "1-2次", "3-4次", "5+次"] },
      { type: "checkbox", label: "你有以下哪些饮食习惯?", name: "dietHabits", options: ["素食", "低糖", "高蛋白", "无特殊"] }
    ]
  },
  // 可以继续添加更多步骤...
];

这样的结构能让你后续渲染步骤内容时更有条理。

2. 用Vue响应式状态跟踪当前步骤

在Vue组件里,你只需要一个简单的响应式变量来记录当前显示的步骤索引,比如:

<script setup>
import { ref } from 'vue';

// 跟踪当前步骤的索引,从0开始对应第一个步骤
const currentStepIndex = ref(0);
// 定义问卷步骤数据
const surveySteps = [/* 上面的数组内容 */];
// 用来收集用户填写的表单数据
const formData = ref({});
</script>

3. 渲染当前步骤的内容

在模板里,根据currentStepIndex的值来渲染对应的步骤内容,同时绑定表单数据:

<template>
  <div class="survey-wrapper">
    <!-- 当前步骤的标题 -->
    <h2>{{ surveySteps[currentStepIndex].title }}</h2>

    <!-- 渲染当前步骤的所有问题 -->
    <div class="question-section">
      <div v-for="question in surveySteps[currentStepIndex].questions" :key="question.name" class="question-item">
        <label class="question-label">{{ question.label }} <span v-if="question.required">*</span></label>
        
        <!-- 文本输入框 -->
        <input 
          v-if="question.type === 'text'" 
          type="text" 
          v-model="formData[question.name]" 
          :placeholder="`请输入${question.label}`"
        >

        <!-- 下拉选择框 -->
        <select v-else-if="question.type === 'select'" v-model="formData[question.name]">
          <option value="">请选择</option>
          <option v-for="option in question.options" :key="option" :value="option">{{ option }}</option>
        </select>

        <!-- 单选按钮组 -->
        <div v-else-if="question.type === 'radio'" class="radio-group">
          <label v-for="option in question.options" :key="option" class="radio-item">
            <input type="radio" v-model="formData[question.name]" :value="option">
            {{ option }}
          </label>
        </div>

        <!-- 多选框组 -->
        <div v-else-if="question.type === 'checkbox'" class="checkbox-group">
          <label v-for="option in question.options" :key="option" class="checkbox-item">
            <input type="checkbox" v-model="formData[question.name]" :value="option">
            {{ option }}
          </label>
        </div>
      </div>
    </div>

    <!-- 导航按钮区域 -->
    <div class="nav-buttons">
      <button @click="goPrevious" :disabled="currentStepIndex === 0">上一步</button>
      <button 
        @click="goNext" 
        :disabled="currentStepIndex === surveySteps.length - 1 || !validateCurrentStep()"
      >
        {{ currentStepIndex === surveySteps.length - 1 ? '提交' : '下一步' }}
      </button>
    </div>
  </div>
</template>

4. 实现切换与验证逻辑

在<script setup>里添加对应的方法,处理步骤切换和必填项验证:

// 切换到上一步
const goPrevious = () => {
  if (currentStepIndex.value > 0) {
    currentStepIndex.value--;
  }
};

// 切换到下一步,先验证当前步骤
const goNext = () => {
  if (validateCurrentStep()) {
    if (currentStepIndex.value < surveySteps.length - 1) {
      currentStepIndex.value++;
    } else {
      // 最后一步,提交表单
      handleSubmit();
    }
  }
};

// 验证当前步骤的必填项
const validateCurrentStep = () => {
  const currentQuestions = surveySteps[currentStepIndex.value].questions;
  for (const question of currentQuestions) {
    if (question.required && !formData.value[question.name]) {
      alert(`${question.label}为必填项,请填写`);
      return false;
    }
  }
  return true;
};

// 提交问卷的逻辑
const handleSubmit = () => {
  // 这里可以把formData发送到后端,或者做其他处理
  console.log('问卷提交数据:', formData.value);
  alert('问卷提交成功!');
};

5. 基础样式优化(可选)

给页面加一些简单的样式,让布局更美观:

<style scoped>
.survey-wrapper {
  max-width: 700px;
  margin: 3rem auto;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.question-section {
  margin: 2rem 0;
}

.question-item {
  margin-bottom: 1.5rem;
}

.question-label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
}

input[type="text"], select {
  width: 100%;
  padding: 0.8rem;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.radio-group, .checkbox-group {
  display: flex;
  gap: 1.5rem;
  margin-top: 0.5rem;
}

.nav-buttons {
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
  margin-top: 2rem;
}

button {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 4px;
  background-color: #2563eb;
  color: white;
  cursor: pointer;
  font-size: 1rem;
}

button:disabled {
  background-color: #94a3b8;
  cursor: not-allowed;
}
</style>

额外小贴士

  • 如果需要保存用户的填写进度,可以用localStorage把formData和currentStepIndex存起来,页面刷新后再读取恢复
  • 要是后续想扩展功能,比如步骤进度条,可以根据currentStepIndex和总步骤数来计算进度比例
  • 验证逻辑可以更精细化,比如邮箱格式、数字范围等,不用局限于简单的必填检查

这样一步步下来,你就能快速搭建出一个具备幻灯片切换功能的问卷了,先从最小的demo开始测试,再逐步扩展更多内容~

内容的提问来源于stack exchange,提问作者silverburd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:05:07