| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- <script setup lang="ts">
- import { computed, nextTick, onMounted, ref, unref } from 'vue';
- import { useDebounceFn } from '@vueuse/core';
- import { get } from '@/utils/zt/lodashChunk';
- import { isFunction } from '@/utils/zt/is';
- import { basicApiSelectProps } from './props';
- import type { ApiSelectProps } from './type';
- const debouncedFn = useDebounceFn(() => {
- fetchApi();
- }, 1000);
- const props = withDefaults(defineProps<ApiSelectProps>(), {
- immediate: true,
- resultFeild: 'data',
- clearable: true,
- pagination: false,
- pageNumFeild: 'current',
- pageSizeFeild: 'size'
- });
- const fetchLoading = ref(false);
- const basicProps = ref(basicApiSelectProps);
- const options = ref<Recordable[]>([]);
- const modelVlaue = defineModel<Array<string | number> | string | number | null>();
- const isFirstReq = ref(false);
- const searchText = ref('');
- const total = ref(0);
- const page = ref(1);
- const bindValue = computed(() => {
- return {
- ...props,
- ...basicProps
- };
- });
- async function fetchApi() {
- const api = props.api;
- if (!api || !isFunction(api)) return;
- const params = {
- ...props.params
- };
- if (unref(bindValue).filterFeild && unref(searchText)) {
- params[String(unref(bindValue).filterFeild)] = unref(searchText);
- // console.log(params, 'apiselect请求参数');
- }
- if (unref(bindValue).pagination) {
- params[unref(bindValue).pageNumFeild] = unref(page);
- params[unref(bindValue).pageSizeFeild] = 10;
- }
- const res = await api(params);
- options.value = unref(bindValue).pagination ? [...options.value, ...res.data.records] : get(res, props.resultFeild);
- fetchLoading.value = false;
- if (props.setDefaultValue) {
- console.log(options.value[0], unref(bindValue).valueFeild, 'options.value');
- nextTick(() => {
- modelVlaue.value = options.value[0][unref(bindValue).valueFeild as string];
- console.log(modelVlaue.value, '默认值');
- });
- }
- if (props.getOptions) {
- props.getOptions(options.value);
- }
- if (unref(bindValue).pagination) {
- total.value = res.data.total;
- }
- }
- onMounted(() => {
- if (unref(bindValue).immediate) {
- fetchApi();
- }
- });
- function handleFocus() {
- if (!unref(bindValue).immediate && !unref(isFirstReq)) {
- fetchApi();
- isFirstReq.value = true;
- }
- if (!unref(options).length && unref(bindValue).immediate) {
- fetchApi();
- }
- }
- function handleScroll(e: Event) {
- const currentTarget = e.currentTarget as HTMLElement;
- if (currentTarget.scrollTop + currentTarget.offsetHeight >= currentTarget.scrollHeight) {
- // console.log('到底了');
- if (options.value.length < total.value && !fetchLoading.value) {
- // console.log('请求数据');
- fetchLoading.value = true;
- page.value += 1;
- fetchApi();
- }
- }
- }
- function handleSearch(value: string) {
- fetchLoading.value = true;
- searchText.value = value;
- debouncedFn();
- }
- function handleClear() {
- searchText.value = '';
- fetchApi();
- }
- function handleBlur() {
- searchText.value = '';
- }
- </script>
- <template>
- <NSelect
- v-bind="bindValue"
- v-model:value="modelVlaue"
- :options="options"
- :label-field="labelFeild"
- :value-field="valueFeild"
- :loading="fetchLoading"
- @focus="handleFocus"
- @scroll="handleScroll"
- @search="handleSearch"
- @clear="handleClear"
- @blur="handleBlur"
- ></NSelect>
- </template>
- <style scoped></style>
|