| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- <script setup lang="ts">
- import type { FetchDataCallback, FetchSelectedDataCallback, PageParameters, SelectPageKey } from 'v-selectpage';
- import { SelectPageList } from 'v-selectpage';
- const props = withDefaults(defineProps<{
- load(page: number, size: number, query?: Record<string, any>): Promise<{ data: any[]; total: number }>;
- query?: Record<string, any>;
- keyProp?: string;
- labelProp?: string;
- }>(), {
- keyProp: 'id',
- labelProp: 'name',
- });
- const emits = defineEmits<{
- update: [ value: any ]
- }>();
- const attrs = useAttrs() as {
- multiple?: boolean;
- };
- const [ modelValue, modifiers ] = defineModel<any, 'complex'>('value', {
- get(v: any) {
- if ( !v || !v?.length ) return [];
- if ( !Array.isArray(v) ) v = [ v ];
- return v;
- },
- set(v: SelectPageKey[]) {
- return v[ 0 ];
- },
- });
- async function fetchData(data: PageParameters, callback: FetchDataCallback) {
- const { search: keyword, pageNumber, pageSize } = data;
- try {
- const { data, total } = await props.load(pageNumber, pageSize, { ...props.query, keyword });
- callback(data, total);
- } catch ( e ) {
- callback([], 0);
- }
- }
- async function fetchSelectedData(keys: SelectPageKey[], callback: FetchSelectedDataCallback) {
- if ( attrs.multiple ) {
- callback(keys.map(key => (
- {
- [ props.labelProp ]: key,
- [ props.labelProp ]: key,
- }
- )));
- } else {
- try {
- const { data } = await props.load(1, 1, { keyword: keys[ 0 ] });
- callback(data);
- } catch ( e ) {
- callback([]);
- }
- }
- }
- function onSelect(items: Record<string, unknown>[]) {
- emits('update', attrs.multiple ? items : items?.[ 0 ]);
- }
- </script>
- <template>
- <SelectPageList
- language="zh-chs"
- :key-prop="props.keyProp" :label-prop="props.labelProp"
- v-model="modelValue" @fetch-data="fetchData"
- @fetch-selected-data="fetchSelectedData"
- @selection-change="onSelect"
- />
- </template>
- <style lang="scss">
- .v-dropdown-trigger {
- width: 100%;
- .sp-trigger-container {
- padding: 3px 6px;
- border-radius: 6px;
- &.sp-opened,
- &:hover {
- border-color: #6bceff !important;
- }
- &.sp-opened,
- &:focus {
- border-color: #6bceff !important;
- box-shadow: 0 0 0 2px rgba(5, 205, 255, 0.06);
- border-inline-end-width: 1px;
- outline: 0;
- }
- }
- .sp-placeholder {
- color: #e0e0e0 !important;
- }
- }
- </style>
|