feat: 矩阵抽离组件
- 矩阵的三个组件抽离,由 MatrixQuestion 内部管理
This commit is contained in:
@@ -1,86 +1,25 @@
|
||||
<template>
|
||||
<el-table :data="rows" style="width: 100%">
|
||||
<el-table-column :width="tableWidth">
|
||||
<template #header></template>
|
||||
<template #default="{ row /*, column, $index*/ }">
|
||||
<div style="position: relative">
|
||||
<el-text truncated :style="{ width: `${tableWidth}px` }">
|
||||
<contenteditable v-model="row.option" :active="active" @blur="emitValue" />
|
||||
</el-text>
|
||||
<van-popover
|
||||
v-model="row.showAction"
|
||||
placement="left-end"
|
||||
trigger="click"
|
||||
:actions="popoverActions"
|
||||
@select="handleActionSelect($event, row, 'row')"
|
||||
>
|
||||
<template #reference>
|
||||
<div v-if="active" class="icon">
|
||||
<Io5EllipsisVerticalSharp />
|
||||
</div>
|
||||
</template>
|
||||
</van-popover>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-for="(col, colIndex) in cols" :key="col.option" :width="tableWidth">
|
||||
<template #header>
|
||||
<div style="position: relative">
|
||||
<el-text truncated :style="{ width: `${tableWidth}px` }">
|
||||
<contenteditable v-model="col.option" :active="active" @blur="emitValue" />
|
||||
</el-text>
|
||||
<van-popover
|
||||
v-model="col.showAction"
|
||||
placement="left-end"
|
||||
trigger="click"
|
||||
:actions="popoverActions"
|
||||
@select="handleActionSelect($event, col, 'col')"
|
||||
>
|
||||
<template #reference>
|
||||
<div v-if="active" class="icon">
|
||||
<Io5EllipsisVerticalSharp />
|
||||
</div>
|
||||
</template>
|
||||
</van-popover>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="{ /*row, column, */ $index: rowIndex }">
|
||||
<input
|
||||
type="checkbox"
|
||||
:name="`R${rowIndex + 1}`"
|
||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||
@change="handleMatrixCheckboxChange(rowIndex, colIndex)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<input
|
||||
type="checkbox"
|
||||
:name="`R${rowIndex + 1}`"
|
||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||
@change="handleMatrixCheckboxChange(rowIndex, colIndex)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Io5EllipsisVerticalSharp } from 'vue-icons-plus/io5';
|
||||
// 接受获取到的 col row 的索引参数
|
||||
const rowIndex = defineModel<number>('rowIndex', { required: true, default: 0 });
|
||||
const colIndex = defineModel<number>('colIndex', { required: true, default: 0 });
|
||||
|
||||
// 添加激活 action 的选项
|
||||
interface _questionOptionType extends questionOptionType {
|
||||
showAction?: boolean;
|
||||
}
|
||||
|
||||
// 记录行和列的索引
|
||||
const rowRecord = defineModel<number[][]>('rowRecord', { required: false, default: () => [] });
|
||||
// const matrixAnswer = defineModel<{ [key: string]: 1 }>('matrixAnswer', { required: false, default: () => ({}) });
|
||||
// 检查 rowRecord 是否存在
|
||||
// console.log(`rowRecord:`, rowRecord.value);
|
||||
const tableWidth = defineModel<number>('tableWidth', { required: false, default: 110 });
|
||||
const active = defineModel<boolean>('active', { required: false, default: true });
|
||||
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
|
||||
const rows = defineModel<_questionOptionType[]>('rows', { required: false, default: () => [] });
|
||||
const cols = defineModel<_questionOptionType[]>('cols', { required: false, default: () => [] });
|
||||
|
||||
const element = defineModel<question>('element', {
|
||||
required: false,
|
||||
default: () => {
|
||||
/**/
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:matrixAnswer', 'update:rowRecord', 'update:element']);
|
||||
|
||||
// 判断是否选中
|
||||
@@ -95,45 +34,6 @@ const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
||||
return rowRecord.value[rowIndex].includes(colIndex);
|
||||
};
|
||||
|
||||
addShowActionOption();
|
||||
/**
|
||||
* 给行或者列选项 添加 showAction 选项
|
||||
*/
|
||||
function addShowActionOption() {
|
||||
rows.value.forEach((row) => {
|
||||
row.showAction = true;
|
||||
});
|
||||
cols.value.forEach((col) => {
|
||||
col.showAction = true;
|
||||
});
|
||||
}
|
||||
|
||||
// 增加 popover 的 actions
|
||||
const popoverActions = [
|
||||
{
|
||||
text: '删除'
|
||||
}
|
||||
// {
|
||||
// text: '置底'
|
||||
// }
|
||||
];
|
||||
|
||||
// popover 的事件
|
||||
function handleActionSelect(action: { text: string }, axi: any, type: 'row' | 'col') {
|
||||
const data = type === 'row' ? rows : cols;
|
||||
const index = data.value.indexOf(axi);
|
||||
if (index < 0) return;
|
||||
switch (action.text) {
|
||||
case '删除':
|
||||
data.value.splice(index, 1);
|
||||
break;
|
||||
|
||||
case '置底':
|
||||
data.value.push(data.value.splice(index, 1)[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 当 matrix radio 选中时,更新 rowRecord 和 matrixAnswer
|
||||
function handleMatrixCheckboxChange(row: number, col: number) {
|
||||
// 获取 colIndexArray
|
||||
@@ -158,49 +58,3 @@ const emitValue = (/* val: unknown */) => {
|
||||
emit('update:element', element.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/css/theme';
|
||||
|
||||
.matrix-table {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.matrix-checkbox {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 1px solid #f4f4f4;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
appearance: none; /* 去除默认样式 */
|
||||
//transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.matrix-checkbox:checked {
|
||||
border-color: transparent; /* 选中时边框颜色 */
|
||||
}
|
||||
|
||||
.matrix-checkbox:checked::before {
|
||||
content: '\e728';
|
||||
position: absolute;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-color: $theme-color; /* 选中颜色 */
|
||||
color: #fff;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: -10px;
|
||||
|
||||
& > svg {
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user