103 lines
2.8 KiB
Vue
103 lines
2.8 KiB
Vue
<template>
|
|
<div>
|
|
<el-dialog :title="dialogTitle" v-model="csjgVisible" width="300px" :close-on-click-modal="false" :draggable="true">
|
|
<el-input v-model="searchKey" :placeholder="placeholder" size="small" class="mb10" clearable
|
|
@clear="filterDictData" @input="filterDictData" />
|
|
|
|
<el-table :data="filterData" max-height="300px" border @row-dblclick="selectItem" highlight-current-row
|
|
:row-style="{ helght: '25px' }">
|
|
<el-table-column prop="qz" label="取值" align="center" />
|
|
<el-table-column prop="pinyin" label="简拼" align="center" />
|
|
</el-table>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onMounted, ref, watch, computed, reactive, toRaw } from 'vue';
|
|
// @ts-ignore
|
|
import { getFirstLetter } from '@/api/pinyin.js';
|
|
|
|
|
|
interface Props {
|
|
tableData: object[];
|
|
label?: string;
|
|
dialogTitle?: string;
|
|
placeholder?: string;
|
|
|
|
}
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
label: undefined,
|
|
dialogTitle: '选择数据',
|
|
placeholder: '支持简拼搜索'
|
|
});
|
|
const csjgVisible = ref(false)
|
|
const searchKey = ref('')
|
|
const filterData = ref<{ [key: string]: any; pinyinMap: Record<string, string> }[]>([]);
|
|
const filterDictData = () => {
|
|
const key = searchKey.value.trim().toLowerCase();
|
|
|
|
if (!key) {
|
|
// 空搜索时显示全部预处理数据
|
|
filterData.value = [...processedTableData.value];
|
|
return;
|
|
}
|
|
|
|
filterData.value = processedTableData.value.filter((item: any) => {
|
|
// 1. 原文本匹配
|
|
const matchLabel = props.label && item[props.label]?.toString().toLowerCase().includes(key);
|
|
return matchLabel;
|
|
});
|
|
}
|
|
|
|
interface Emits {
|
|
(e: "selectItem", val: any): void;
|
|
}
|
|
const emits = defineEmits<Emits>();
|
|
const selectItem = (row: any) => {
|
|
emits('selectItem', row);
|
|
csjgVisible.value = false;
|
|
}
|
|
// 存储预处理后的带拼音数据
|
|
const processedTableData = ref<{ [key: string]: any; pinyinMap: Record<string, string> }[]>([]);
|
|
// 初始化数据
|
|
onMounted(() => {
|
|
processedTableData.value = processTableData(props.tableData);
|
|
|
|
filterData.value = [...processedTableData.value];
|
|
});
|
|
|
|
// 监听表格数据变化,重新处理
|
|
watch(() => props.tableData, (newVal) => {
|
|
processedTableData.value = processTableData(newVal);
|
|
filterData.value = [...processedTableData.value];
|
|
// 数据回显
|
|
}, { deep: true });
|
|
// 预处理数据:生成拼音信息
|
|
const processTableData = (data: object[]) => {
|
|
return data.map((item: any) => {
|
|
const pinyinMap: Record<string, string> = {};
|
|
// 处理label字段拼音
|
|
if (props.label) {
|
|
pinyinMap['pinyin'] = getFirstLetter(item[props.label]).toLowerCase();
|
|
return { ...item, ...pinyinMap };
|
|
}
|
|
|
|
});
|
|
};
|
|
|
|
const open = () => {
|
|
csjgVisible.value = true;
|
|
};
|
|
|
|
defineExpose({
|
|
open,
|
|
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
:deep(.el-table .el-table__cell) {
|
|
padding: 0;
|
|
}
|
|
</style> |