vue实现问卷联动
Vue 实现问卷联动的方法
问卷联动通常指根据用户的选择动态显示或隐藏相关问题。Vue 的响应式特性和条件渲染可以轻松实现这一功能。
使用 v-if 或 v-show 控制问题显示
通过绑定用户的选择结果,利用 v-if 或 v-show 控制后续问题的显示。v-if 是惰性的,适合不频繁切换的场景;v-show 始终渲染,适合频繁切换。
<template>
<div>
<label>是否拥有汽车?</label>
<select v-model="hasCar">
<option value="yes">是</option>
<option value="no">否</option>
</select>
<div v-if="hasCar === 'yes'">
<label>汽车品牌是什么?</label>
<input type="text" v-model="carBrand">
</div>
</div>
</template>
<script>
export default {
data() {
return {
hasCar: '',
carBrand: ''
}
}
}
</script>
动态表单生成
对于复杂的联动逻辑,可以使用计算属性或方法动态生成问题列表。
<template>
<div>
<div v-for="(question, index) in dynamicQuestions" :key="index">
<label>{{ question.label }}</label>
<input
v-if="question.type === 'text'"
type="text"
v-model="question.value"
>
<select v-else v-model="question.value">
<option
v-for="option in question.options"
:value="option.value"
>
{{ option.text }}
</option>
</select>
</div>
</div>
</template>
<script>
export default {
data() {
return {
baseQuestions: [
{ label: '性别', type: 'select', value: '', options: [
{ value: 'male', text: '男' },
{ value: 'female', text: '女' }
]}
],
answers: {}
}
},
computed: {
dynamicQuestions() {
const questions = [...this.baseQuestions]
if (this.answers.gender === 'female') {
questions.push({
label: '是否怀孕',
type: 'select',
value: '',
options: [
{ value: 'yes', text: '是' },
{ value: 'no', text: '否' }
]
})
}
return questions
}
}
}
</script>
使用状态管理
对于大型问卷应用,建议使用 Vuex 或 Pinia 管理问卷状态,使联动逻辑更清晰。
// store.js (Pinia 示例)
import { defineStore } from 'pinia'
export const useSurveyStore = defineStore('survey', {
state: () => ({
answers: {},
questions: [
{
id: 'q1',
text: '职业',
type: 'select',
options: ['学生', '上班族', '自由职业'],
next: {
'学生': ['q2'],
'上班族': ['q3']
}
},
{ id: 'q2', text: '所在学校', type: 'text' },
{ id: 'q3', text: '公司名称', type: 'text' }
]
}),
getters: {
visibleQuestions(state) {
return state.questions.filter(question => {
// 根据 answers 中的回答决定是否显示问题
return true // 实际应实现具体逻辑
})
}
}
})
表单验证
联动问卷通常需要验证,可以使用 VeeValidate 或 Element UI 等库。
<template>
<Form @submit="onSubmit" :validation-schema="schema">
<Field name="email" type="email" />
<ErrorMessage name="email" />
<Field name="password" type="password" />
<ErrorMessage name="password" />
<button>Submit</button>
</Form>
</template>
<script>
import { Form, Field, ErrorMessage } from 'vee-validate'
import * as yup from 'yup'
export default {
components: {
Form,
Field,
ErrorMessage
},
data() {
const schema = yup.object({
email: yup.string().required().email(),
password: yup.string().required().min(8)
})
return {
schema
}
},
methods: {
onSubmit(values) {
console.log(values)
}
}
}
</script>
注意事项
- 性能优化:避免在计算属性中进行复杂计算,对于大型问卷考虑使用虚拟滚动。
- 用户体验:在隐藏问题时考虑动画过渡效果,避免界面跳跃。
- 数据持久化:如果问卷需要分步完成,考虑将回答保存到本地存储。
- 无障碍访问:确保动态显示的内容对屏幕阅读器友好。







