98 lines
2.7 KiB
Vue
Raw Normal View History

2025-06-05 17:40:58 +08:00
<!-- components/UrlSelect.vue -->
<template>
<el-select
v-bind="$attrs"
v-model="internalValue"
@change="$emit('change', $event)"
@blur="$emit('blur', $event)"
@focus="$emit('focus', $event)"
@clear="$emit('clear', $event)"
@visible-change="$emit('visible-change', $event)"
@remove-tag="$emit('remove-tag', $event)"
@scroll="$emit('scroll', $event)"
>
2025-06-19 13:33:54 +08:00
<template v-for="(_, name) in $slots" #[name]="scopedData">
<slot :name="name" v-bind="scopedData"> </slot>
</template>
2025-06-05 17:40:58 +08:00
<slot name="option-group">
<el-option v-for="item in options" :key="item[valueKey]" :label="item[labelKey]" :value="item[valueKey]" />
</slot>
</el-select>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import request from '@/utils/axios';
// -------------- ① 定义要继承/自定义的 Props --------------
const props = defineProps({
modelValue: {
type: [String, Number, Array],
default: null,
},
url: {
type: String,
default: null,
},
params: {
type: Object,
default: () => ({}),
},
// 可按需让上层指定 label 字段名、value 字段名
labelKey: {
type: String,
default: 'label',
},
valueKey: {
type: String,
default: 'value',
},
2025-06-12 13:11:18 +08:00
responseParser: {
type: Function,
default: (res) => res.data.records, // 默认解析函数
},
2025-06-05 17:40:58 +08:00
});
// -------------- ② 定义要透传回父组件的 Events --------------
const emit = defineEmits(['update:modelValue', 'change', 'blur', 'focus', 'clear', 'visible-change', 'remove-tag', 'scroll']);
// -------------- ③ 内部双向绑定 --------------
// 用一个 ref 存储内部的值
const internalValue = ref(props.modelValue);
// 当 prop 变化时,同步到 internalValue
watch(
() => props.modelValue,
(newVal) => {
internalValue.value = newVal;
}
);
// 当 internalValue 变化时emit update:modelValue
watch(internalValue, (newVal) => {
emit('update:modelValue', newVal);
});
// -------------- ④ 选项列表 --------------
const options = ref([]);
// -------------- ⑤ 请求数据的函数 --------------
async function fetchOptions() {
2025-06-08 20:18:35 +08:00
// console.log('fetchOptions :>> ', props.url, props.params);
2025-06-05 17:40:58 +08:00
if (!props.url) return;
2025-06-08 20:18:35 +08:00
const res = await request.get(props.url, { params: props.params });
2025-06-12 13:11:18 +08:00
const records = props.responseParser(res);
2025-06-08 20:18:35 +08:00
if (Array.isArray(records)) {
options.value = records;
// console.log('option', options.value);
} else {
options.value = [];
2025-06-12 13:11:18 +08:00
console.error('UrlSelect解析后的数据不是数组');
2025-06-05 17:40:58 +08:00
}
}
// -------------- ⑥ 生命周期:组件挂载后立即拉一次数据 --------------
onMounted(() => {
fetchOptions();
});
</script>