133 lines
3.4 KiB
Vue
133 lines
3.4 KiB
Vue
<script setup lang="ts">
|
||
import { useTemplateRef, type Directive } from 'vue';
|
||
|
||
const columnLabels = useTemplateRef<HTMLElement[]>('columnLabels');
|
||
|
||
// 注意, element.options 里面的东西是数组,第一项内容是行标签内容,第二项内容是列标签内容
|
||
// 类型 AI 生成 切勿盲目相信,以实际为准
|
||
const { element } = defineProps<{ element: MatrixSurveyQuestion }>();
|
||
|
||
/**
|
||
* input 类型映射,里面自行处理逻辑返回对应类型
|
||
* // remark: 填空内容 question_type 8
|
||
* // remark: 单选打分矩阵 question_type 9
|
||
* // remark: 多选矩阵内容 question_type 10
|
||
* @default 'radio'
|
||
*/
|
||
const tableInputTypeMapping = (/** regx?: any */) => {
|
||
switch (element.question_type) {
|
||
case 8:
|
||
return 'text';
|
||
case 9:
|
||
return 'radio';
|
||
case 10:
|
||
return 'checkbox';
|
||
default:
|
||
return 'radio';
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 自定义指令,用于在元素挂载后自动获取焦点
|
||
*/
|
||
const vFocus: Directive = {
|
||
mounted(el: HTMLInputElement) {
|
||
el.focus();
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<van-cell>
|
||
<!-- 使用 title 插槽来自定义标题 -->
|
||
<template #title>
|
||
<span>
|
||
<span v-if="element?.config?.is_required">*</span>
|
||
<span v-html="element.title"></span>
|
||
<span v-html="element.stem"></span>
|
||
</span>
|
||
</template>
|
||
|
||
<!-- 使用 label 插槽来自定义标题 -->
|
||
<template #label>
|
||
<table class="martrix-table">
|
||
<thead>
|
||
<tr>
|
||
<!-- 第一行内容为空 -->
|
||
<th></th>
|
||
<!-- 第二行内容开始填充 -->
|
||
<td v-for="col in element.options[1]" :key="col.option" ref="columnLabels">
|
||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||
<input
|
||
v-if="col.editor"
|
||
v-model="col.option"
|
||
v-focus
|
||
type="text"
|
||
@focusout="col.editor = false"
|
||
/>
|
||
<span v-else @click="col.editor = true" v-html="col.option"></span>
|
||
</td>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="row in element.options[0]" :key="row.option">
|
||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||
<td>
|
||
<input
|
||
v-if="row.editor"
|
||
v-model="row.option"
|
||
v-focus
|
||
type="text"
|
||
@focusout="row.editor = false"
|
||
/>
|
||
<span v-else @click="row.editor = true" v-html="row.option"></span>
|
||
</td>
|
||
<td v-for="col in element.options[1]" :key="col.option">
|
||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||
<input :id="col.option" :type="tableInputTypeMapping()" :name="row.option" />
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</template>
|
||
</van-cell>
|
||
</template>
|
||
<style scoped lang="scss">
|
||
.martrix-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
color: black;
|
||
|
||
th,
|
||
td {
|
||
padding: 8px;
|
||
border: 1px solid #ddd;
|
||
border-width: 0 0 1px;
|
||
text-align: left;
|
||
}
|
||
}
|
||
|
||
input[type='text'] {
|
||
width: 85%;
|
||
}
|
||
|
||
.martrix-table-action {
|
||
margin-top: 10px;
|
||
|
||
.van-icon {
|
||
color: lightgreen;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.martrix-table-action-tool {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
|
||
& > span {
|
||
margin-right: 6px;
|
||
font-size: 16px;
|
||
}
|
||
}
|
||
}
|
||
</style>
|