100 lines
2.1 KiB
Plaintext
100 lines
2.1 KiB
Plaintext
<template>
|
|
<div class="BasicSelect">
|
|
<a-select v-bind="getBindValues">
|
|
<template v-for="item in Object.keys($slots)" :key="item" #[item]="data">
|
|
<slot v-bind="data" :name="item"></slot>
|
|
</template>
|
|
</a-select>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, unref, computed, onMounted, useAttrs } from 'vue';
|
|
import { basicProps } from './props';
|
|
import { createStorage } from '@/utils/Storage';
|
|
|
|
const Storage = createStorage({ storage: localStorage });
|
|
|
|
const props = defineProps({ ...basicProps });
|
|
|
|
const loading = ref(true);
|
|
|
|
const options = ref([]);
|
|
|
|
const attrs = useAttrs();
|
|
|
|
const getProps = computed(() => {
|
|
return { ...props } as basicProps;
|
|
});
|
|
|
|
const selectWidth = props.block ? '100%' : `${props.width}px`;
|
|
|
|
const getBindValues = computed(() => {
|
|
return {
|
|
...unref(getProps),
|
|
loading: loading.value,
|
|
options: options.value,
|
|
...attrs,
|
|
};
|
|
});
|
|
|
|
const getCacheData = computed(() => {
|
|
return props.cacheKey ? Storage.get(props.cacheKey) : null;
|
|
});
|
|
|
|
//初始化
|
|
function init() {
|
|
const { cache, cacheKey } = props;
|
|
//判断是否启用缓存
|
|
if (cache && cacheKey && getCacheData.value) {
|
|
options.value = getCacheData.value || [];
|
|
loading.value = false;
|
|
return;
|
|
}
|
|
//获取新数据
|
|
fetch();
|
|
}
|
|
|
|
//触发取新数据
|
|
async function fetch() {
|
|
loading.value = true;
|
|
const { request, cacheKey } = props;
|
|
try {
|
|
const res = await request();
|
|
options.value = res || [];
|
|
loading.value = false;
|
|
Storage.set(cacheKey, res);
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
//获取数据源
|
|
function getData() {
|
|
const { cache, cacheKey } = props;
|
|
return cache && cacheKey ? Storage.get(props.cacheKey) : options.value;
|
|
}
|
|
|
|
//获取缓存
|
|
onMounted(() => {
|
|
init();
|
|
});
|
|
|
|
//暴露方法
|
|
defineExpose({
|
|
fetch,
|
|
getData,
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.BasicSelect {
|
|
display: inline-block;
|
|
width: v-bind(selectWidth);
|
|
|
|
.ant-select {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|