feat: 抽离答题校验逻辑

- 现在可以自由控制校验答题时间.
- 增加 useValidateQuestion hooks.
- 多选矩阵应用这个逻辑,组件添加时添加到验证列表,卸载时移除对应的函数 validateFun
This commit is contained in:
Huangzhe
2025-04-01 14:12:07 +08:00
parent aff908e7e6
commit 7de06d5ff4
3 changed files with 45 additions and 5 deletions

View File

@@ -538,6 +538,10 @@ import PreviewCheckbox from '@/views/Survey/views/Preview/components/questions/P
import PreviewRate from '@/views/Survey/views/Preview/components/questions/PreviewRate.vue';
import PreviewSign from '@/views/Survey/views/Preview/components/questions/PreviewSign.vue';
import PreviewTextWithImages from '@/views/Survey/views/Preview/components/questions/PreviewTextWithImages.vue';
import {
startValidate,
validateList
} from '@/views/Survey/views/Preview/hooks/useValidateQuestion';
const isPreview = defineModel('isPreview', {
type: Boolean,
@@ -610,6 +614,8 @@ async function previous() {
// 下一页
async function next(callbackBeforePage) {
// 开始校验答案
startValidate();
// console.log(`click next button`, prevLoading.value || loading.value);
// if (prevLoading.value || loading.value) {
// return;

View File

@@ -3,8 +3,8 @@
:index="answerIndex"
v-model:rowRecord="rowRecord"
v-model:matrix-radio-answer="answer!"
:rows="rows"
:cols="cols"
:rows="rows.options"
:cols="cols.options"
:is-preview="true"
:errorMessage="question.error"
:element="question"
@@ -13,11 +13,12 @@
<script setup lang="ts">
import MatrixQuestion from '@/views/Design/components/Questions/MatrixQuestion.vue';
import { computed, ref, watch } from 'vue';
import { computed, onUnmounted, ref, watch } from 'vue';
import type { IQuestion, IQuestionOption } from '@/types/question';
import { validateMatrixCheckbox } from '@/views/Survey/views/Preview/components/questions/validate/validateMatrixCheckbox';
import type { MatrixCheckboxAnswerType } from '@/views/Survey/views/Preview/components/questions/types/previewMatrix';
import type { IMatrixCheckboxConfig } from '@/types/questions/matrixCheckbox';
import { validateList } from '@/views/Survey/views/Preview/hooks/useValidateQuestion';
// const questionType = defineModel<number>('questionType', { required: false });
@@ -80,6 +81,23 @@ function parseAnswer(answer: MatrixCheckboxAnswerType) {
return rowRecordList;
}
// 将校验函数 push 给 validateList以便与点击下一页进行校验。
// 备选方法,此外还可以兼容 pc 答题行为
const validateFun = () => {
question.value.error = validateMatrixCheckbox(
rowRecord.value,
question.value.config!,
question.value.list as IQuestionOption[]
);
};
validateList.value.push(validateFun);
onUnmounted(() => {
// 在页面卸载的时候,将校验函数从 validateList 中移除
validateList.value = validateList.value.filter((func) => func !== validateFun);
console.log(`onUnmounted`, validateList.value);
});
// 查看parseAnswer的返回值
// console.log(`parseAnswer value:`, parseAnswer(answer.value!))
@@ -88,8 +106,7 @@ function parseAnswer(answer: MatrixCheckboxAnswerType) {
* 行的内容在 question.list[0].options
* 列的内容在 question.list[1].options
*/
const rows = computed(() => question.value?.list[0]?.options ?? []);
const cols = computed(() => question.value?.list[1]?.options ?? []);
const [rows, cols] = question.value?.list;
watch(
rowRecord,

View File

@@ -0,0 +1,17 @@
import { ref } from 'vue';
// 需要校验的题目 函数
const validateList = ref<Function[]>([]);
// 开始校验
function startValidate() {
// 如果有需要校验的题目,就开始校验
validateList.value.length &&
validateList.value?.forEach((item) => {
item();
});
return true;
}
export { startValidate, validateList };