feat: 矩阵问卷可以左右滑动

- 矩阵多选、矩阵填空现在可以左右滚动
This commit is contained in:
Huangzhe
2025-03-19 17:51:36 +08:00
parent 1356c5e72c
commit aa1e26cc0b
5 changed files with 83 additions and 117 deletions

View File

@@ -74,7 +74,7 @@ const emitValue = () => {
v-model:element="question" v-model:element="question"
v-model:rows="rows" v-model:rows="rows"
v-model:cols="cols" v-model:cols="cols"
:isPreview="isPreview" :is-preview="isPreview"
style="overflow: scroll; width: 88vw" style="overflow: scroll; width: 88vw"
/> />
</template> </template>

View File

@@ -1,42 +1,31 @@
<template> <template>
<table class="matrix-table"> <el-table :data="rows" style="width: 100%">
<thead> <el-table-column width="140">
<tr> <template #header></template>
<th></th> <template #default="{ row /*, column, $index*/ }">
<td v-for="col in cols" :key="col.option">
<contenteditable v-model="col.option" :active="active" @blur="emitValue" />
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<!-- <input-->
<!-- v-if="col.editor"-->
<!-- v-model="col.option"-->
<!-- v-focus-->
<!-- type="text"-->
<!-- @focusout="col.editor = false"-->
<!-- @click="handleRowNameChange(col.option!)"-->
<!-- />-->
<!-- <span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>-->
</td>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
<!-- <th v-html="row.option"></th>-->
<contenteditable v-model="row.option" :active="active" @blur="emitValue" /> <contenteditable v-model="row.option" :active="active" @blur="emitValue" />
</template>
<th v-for="(col, colIndex) in cols" :key="colIndex"> </el-table-column>
<input <el-table-column v-for="(col, colIndex) in cols" :key="col.option" width="100">
class="van-icon matrix-checkbox" <template #header>
type="checkbox" <contenteditable
:name="`R${rowIndex + 1}`" v-if="col.option"
:value="`${rowIndex + 1}_${colIndex + 1}`" v-model="col.option"
:checked="isOptionChecked(rowIndex, colIndex)" :active="active"
@change="handleMatrixRadioChange(rowIndex, colIndex)" @blur="emitValue"
/> />
</th> <van-field v-else v-model="col.option" placeholder="请输入"></van-field>
</tr> </template>
</tbody> <template #default="{ /*row, column, */ $index: rowIndex }">
</table> <input
type="checkbox"
:name="`R${rowIndex + 1}`"
:checked="isOptionChecked(rowIndex, colIndex)"
@change="handleMatrixCheckboxChange(rowIndex, colIndex)"
/>
</template>
</el-table-column>
</el-table>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -51,14 +40,17 @@ const rowRecord = defineModel<number[][]>('rowRecord', { required: false, defaul
const active = defineModel<boolean>('active', { required: false, default: true }); const active = defineModel<boolean>('active', { required: false, default: true });
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false }); /* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
const rows = defineModel<number[]>('rows', { required: false, default: () => [] }); const rows = defineModel<questionOptionType[]>('rows', { required: false, default: () => [] });
const cols = defineModel<number[]>('cols', { required: false, default: () => [] }); const cols = defineModel<questionOptionType[]>('cols', { required: false, default: () => [] });
const element = defineModel<question>('element', {
required: false,
default: () => {
/**/
}
});
// const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']); const emit = defineEmits(['update:matrixAnswer', 'update:rowRecord', 'update:element']);
const emitValue = () => {
emit('update:element', element.value);
};
// 判断是否选中 // 判断是否选中
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => { const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
// [ // [
@@ -77,7 +69,7 @@ const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
// }; // };
// 当 matrix radio 选中时,更新 rowRecord 和 matrixAnswer // 当 matrix radio 选中时,更新 rowRecord 和 matrixAnswer
function handleMatrixRadioChange(row: number, col: number) { function handleMatrixCheckboxChange(row: number, col: number) {
// 获取 colIndexArray // 获取 colIndexArray
if (!rowRecord.value[row]) { if (!rowRecord.value[row]) {
// 如果没有对应的row创建一个 // 如果没有对应的row创建一个
@@ -113,6 +105,9 @@ function handleMatrixRadioChange(row: number, col: number) {
// emits('update:matrixAnswer', props.matrixAnswer); // emits('update:matrixAnswer', props.matrixAnswer);
// emits('update:rowRecord', props.rowRecord); // emits('update:rowRecord', props.rowRecord);
// }; // };
const emitValue = (/*val: unknown*/) => {
emit('update:element', element.value);
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -1,39 +1,10 @@
<template> <template>
<!-- <table class="matrix-table">-->
<!-- <thead>-->
<!-- <tr>-->
<!-- <th></th>-->
<!-- <th v-for="col in cols" :key="col.option">-->
<!-- <contenteditable-->
<!-- v-if="col.option"-->
<!-- v-model="col.option"-->
<!-- :active="active"-->
<!-- @blur="emitValue"-->
<!-- />-->
<!-- <van-field v-else placeholder="请输入" v-model="col.option" v-focus />-->
<!-- </th>-->
<!-- </tr>-->
<!-- </thead>-->
<!-- <tbody>-->
<!-- <tr v-for="(row, rowIndex) in rows" :key="rowIndex">-->
<!-- <contenteditable v-model="row.option" :active="active" @blur="emitValue" />-->
<!-- <td v-for="(col, colIndex) in cols" :key="colIndex">-->
<!-- <input-->
<!-- type="radio"-->
<!-- class="van-icon matrix-radio"-->
<!-- :name="`R${rowIndex + 1}`"-->
<!-- :value="`${rowIndex + 1}_${colIndex + 1}`"-->
<!-- :checked="isOptionChecked(rowIndex, colIndex)"-->
<!-- @change="handleMatrixRadioChange(rowIndex, colIndex)"-->
<!-- />-->
<!-- </td>-->
<!-- </tr>-->
<!-- </tbody>-->
<!-- </table>-->
<el-table :data="rows" style="width: 100%"> <el-table :data="rows" style="width: 100%">
<el-table-column width="140"> <el-table-column width="80">
<template #header></template> <template #header></template>
<template #default="{ row /*, column, $index*/ }"> <div v-html="row.option"></div></template> <template #default="{ row /*, column, $index*/ }">
<contenteditable v-model="row.option" :active="active" @blur="emitValue" />
</template>
</el-table-column> </el-table-column>
<el-table-column v-for="(col, colIndex) in cols" :key="col.option" width="100"> <el-table-column v-for="(col, colIndex) in cols" :key="col.option" width="100">
<template #header> <template #header>

View File

@@ -1,40 +1,31 @@
<template> <template>
<table class="matrix-table"> <el-table :data="rows" style="width: 100%">
<thead> <el-table-column width="140">
<tr> <template #header></template>
<th></th> <template #default="{ row /*, column, $index*/ }">
<th v-for="col in cols" :key="col.option">
<contenteditable v-model="col.option" :active="active" @blur="emitValue" />
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<!-- <input-->
<!-- v-if="col.editor"-->
<!-- v-model="col.option"-->
<!-- v-focus-->
<!-- type="text"-->
<!-- @focusout="col.editor = false"-->
<!-- @click="handleRowNameChange(col.option!)"-->
<!-- />-->
<!-- <span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>-->
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
<!-- <th v-html="row.option"></th>-->
<contenteditable v-model="row.option" :active="active" @blur="emitValue" /> <contenteditable v-model="row.option" :active="active" @blur="emitValue" />
</template>
<td v-for="(col, colIndex) in cols" :key="colIndex"> </el-table-column>
<input <el-table-column v-for="(col, colIndex) in cols" :key="col.option" width="100">
type="text" <template #header>
placeholder="请输入" <contenteditable
:name="`R${rowIndex + 1}`" v-if="col.option"
:value="getInputValue(rowIndex, colIndex)" v-model="col.option"
@change="handleMatrixTextChange(rowIndex, colIndex, $event)" :active="active"
/> @blur="emitValue"
</td> />
</tr> <van-field v-else v-model="col.option" placeholder="请输入"></van-field>
</tbody> </template>
</table> <template #default="{ /*row, column, */ $index: rowIndex }">
<input
type="text"
:name="`R${rowIndex + 1}`"
:value="getInputValue(rowIndex, colIndex)"
@change="handleMatrixTextChange(rowIndex, colIndex, $event)"
/>
</template>
</el-table-column>
</el-table>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -44,7 +35,12 @@ const rowRecord = defineModel<string[][]>('rowRecord', { required: false, defaul
// 检查 rowRecord 是否存在 // 检查 rowRecord 是否存在
// console.log(`rowRecord:`, rowRecord.value); // console.log(`rowRecord:`, rowRecord.value);
const active = defineModel<boolean>('active', { required: false, default: true }); const active = defineModel<boolean>('active', { required: false, default: true });
const element = defineModel<question>('element', {
required: false,
default: () => {
/**/
}
});
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false }); /* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
const rows = defineModel<questionOptionType[]>('rows', { required: false, default: () => [] }); const rows = defineModel<questionOptionType[]>('rows', { required: false, default: () => [] });
const cols = defineModel<questionOptionType[]>('cols', { required: false, default: () => [] }); const cols = defineModel<questionOptionType[]>('cols', { required: false, default: () => [] });

View File

@@ -1,17 +1,21 @@
<template> <template>
<MatrixText <MartrixQuestion
v-model:rowRecord="rowRecord" v-model:rowRecord="rowRecord"
v-model:matrix-radio-answer="answer!"
:rows="rows" :rows="rows"
:cols="cols" :cols="cols"
:index="questionIndex"
:element="question"
:is-preview="true" :is-preview="true"
:active="false"
/> />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MatrixText from '@/views/Design/components/Questions/MatrixText.vue'; // import MatrixText from '@/views/Design/components/Questions/MatrixText.vue';
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import MartrixQuestion from '@/views/Design/components/Questions/MartrixQuestion.vue';
// const questionType = defineModel<number>('questionType', { required: false }); // const questionType = defineModel<number>('questionType', { required: false });
const questionIndex = defineModel<number>('questionIndex', { required: false, default: 0 });
// 矩阵多选的答案类型 // 矩阵多选的答案类型
type answerType = { type answerType = {