组件
<template>
<div>
<el-select
style="width: 240px"
id="select"
ref="selectTable"
v-model="selectShowValue"
:placeholder="props.placeholder"
:size="props.size"
:clearable="props.clearable"
:filterable="editable"
@input="handleSelectInput"
>
<template #empty>
<el-table
height="250"
ref="table"
:data="props.tableData"
:highlight-current-row="props.isHighlight"
:size="props.size"
:border="props.border"
@current-change="handleCurrentChange"
style="width: 100%;"
>
<el-table-column
v-for="field in props.fields"
:prop="field.prop"
:label="field.label"
:width="field.width"
:show-overflow-tooltip="field.showTooltip"
/>
</el-table>
</template>
</el-select>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from "vue";
interface Field {
prop: string;
label: string;
width: number;
showTooltip?: boolean;
}
interface Props {
data: any;
fields: Field[];
tableData: object[];
isHighlight?: boolean;
border?: boolean;
label?: string;
value?: string;
objKey?: string;
placeholder?: string;
clearable?: boolean;
editable?: boolean;
size?: string;
}
const props = withDefaults(defineProps<Props>(), {
placeholder: "请选择",
size: "default",
isHighlight: true,
value: undefined,
label: undefined,
border: false,
clearable: false,
editable: false,
});
interface Emits {
(e: "update:data", val: any): void;
(e: "inputChange", val: string): void;
}
const emits = defineEmits<Emits>();
const selectTable = ref();
const table = ref();
const selectShowValue = ref(null);
const rowObj = ref(null);
const data = computed({
get() {
return props.data;
},
set(val) {
emits("update:data", val);
},
});
watch(data, (newVal) => {
if (newVal) {
if (typeof props.label !== "undefined") {
if (typeof props.value !== "undefined") {
let row = props.tableData.find(
(item) => item[props.value] === props.data
);
selectShowValue.value =
typeof row === "undefined" ? props.data : row[props.label];
} else if (typeof props.objKey !== "undefined") {
let row = props.tableData.find(
(item) => item[props.objKey] === props.data[props.objKey]
);
selectShowValue.value =
typeof row === "undefined" ? props.data : row[props.label];
}
} else {
if (typeof props.value !== "undefined") {
let row = props.tableData.find(
(item) => item[props.value] === props.data
);
selectShowValue.value =
typeof row === "undefined" ? props.data : row[props.value];
} else if (typeof props.objKey !== "undefined") {
let row = props.tableData.find(
(item) => item[props.objKey] === props.data
);
selectShowValue.value =
typeof row === "undefined" ? props.data : row[props.objKey];
}
}
}
});
watch(selectShowValue, (newVal) => {
if (newVal === "") {
emits("update:data", newVal);
table.value.setCurrentRow(null);
}
});
const handleCurrentChange = (val: any) => {
if (!val) {
return;
}
rowObj.value = { ...val };
setLabel(val);
if (typeof props.value !== "undefined") {
emits("update:data", val[props.value]);
} else {
emits("update:data", val);
}
selectTable.value.blur();
};
const handleSelectInput = () => {
emits("inputChange", document.getElementById("select").value);
};
const setLabel = (val: any) => {
if (typeof props.label === "undefined") {
if (typeof props.value !== "undefined") {
selectShowValue.value = val[props.value];
} else if (typeof props.objKey !== "undefined") {
selectShowValue.value = val[props.objKey];
}
} else {
selectShowValue.value = val[props.label];
}
};
</script>
<style scoped>
.paging {
width: 100%;
display: flex;
justify-content: center;
}
</style>
引用
<template>
<div>
<SelectTable
v-model:data="data"
:fields="fields"
:tableData="tableData"
:label="label"
:objKey="objKey"
:border="true"
clearable
editable
@inputChange="inputChange"
></SelectTable>
</div>
</template>
<script setup lang="ts">
import SelectTable from "./components/SelectTable.vue";
import { ref } from "vue";
const data = ref();
const objKey = ref("itemid");
const label = ref("itemid");
const fields = [
{
prop: "itemid",
label: "ID",
width: 180,
},
{
prop: "product",
label: "产品",
width: 180,
},
{
prop: "price",
label: "价格",
width: 200,
},
];
const tableData = ref([
{
"itemid": "EST-11",
"product": "Iguana",
"price": 18.5
},
{
"itemid": "EST-12",
"product": "Rattlesnake",
"price": 28.5
},
{
"itemid": "EST-13",
"product": "Manx",
"price": 38.5
},
{
"itemid": "EST-15",
"product": "Rattlesnake",
"price": 48.5
},
{
"itemid": "EST-16",
"product": "Amazon Parrot",
"price": 58.5
},
{
"itemid": "EST-17",
"product": "Koi",
"price": 68.5
},
{
"itemid": "EST-19",
"product": "Dalmation",
"price": 78.5
}
]);
const inputChange = (val: string) => {
console.log(val);
};
</script>
<style scoped></style>
效果