Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev
						commit
						f4b03b6101
					
				|  | @ -150,8 +150,8 @@ export async function saveUserApi(user: UserInfo) { | ||||||
| ```ts | ```ts | ||||||
| import { requestClient } from '#/api/request'; | import { requestClient } from '#/api/request'; | ||||||
| 
 | 
 | ||||||
| export async function deleteUserApi(user: UserInfo) { | export async function deleteUserApi(userId: number) { | ||||||
|   return requestClient.delete<boolean>(`/user/${user.id}`, user); |   return requestClient.delete<boolean>(`/user/${userId}`); | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -180,8 +180,8 @@ export async function saveUserApi(user: UserInfo) { | ||||||
| ```ts | ```ts | ||||||
| import { requestClient } from '#/api/request'; | import { requestClient } from '#/api/request'; | ||||||
| 
 | 
 | ||||||
| export async function deleteUserApi(user: UserInfo) { | export async function deleteUserApi(userId: number) { | ||||||
|   return requestClient.delete<boolean>(`/user/${user.id}`, user); |   return requestClient.delete<boolean>(`/user/${userId}`); | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,15 @@ | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import type { DrawerProps, ExtendedDrawerApi } from './drawer'; | import type { DrawerProps, ExtendedDrawerApi } from './drawer'; | ||||||
| 
 | 
 | ||||||
| import { computed, provide, ref, unref, useId, watch } from 'vue'; | import { | ||||||
|  |   computed, | ||||||
|  |   onDeactivated, | ||||||
|  |   provide, | ||||||
|  |   ref, | ||||||
|  |   unref, | ||||||
|  |   useId, | ||||||
|  |   watch, | ||||||
|  | } from 'vue'; | ||||||
| 
 | 
 | ||||||
| import { | import { | ||||||
|   useIsMobile, |   useIsMobile, | ||||||
|  | @ -94,6 +102,16 @@ const { | ||||||
| //   }, | //   }, | ||||||
| // ); | // ); | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * 在开启keepAlive情况下 直接通过浏览器按钮/手势等返回 不会关闭弹窗 | ||||||
|  |  */ | ||||||
|  | onDeactivated(() => { | ||||||
|  |   // 如果弹窗没有被挂载到内容区域,则关闭弹窗 | ||||||
|  |   if (!appendToMain.value) { | ||||||
|  |     props.drawerApi?.close(); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| function interactOutside(e: Event) { | function interactOutside(e: Event) { | ||||||
|   if (!closeOnClickModal.value || submitting.value) { |   if (!closeOnClickModal.value || submitting.value) { | ||||||
|     e.preventDefault(); |     e.preventDefault(); | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ import { | ||||||
|   h, |   h, | ||||||
|   inject, |   inject, | ||||||
|   nextTick, |   nextTick, | ||||||
|   onDeactivated, |  | ||||||
|   provide, |   provide, | ||||||
|   reactive, |   reactive, | ||||||
|   ref, |   ref, | ||||||
|  | @ -72,13 +71,6 @@ export function useVbenDrawer< | ||||||
|       }, |       }, | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 在开启keepAlive情况下 直接通过浏览器按钮/手势等返回 不会关闭弹窗 |  | ||||||
|      */ |  | ||||||
|     onDeactivated(() => { |  | ||||||
|       (extendedApi as ExtendedDrawerApi)?.close?.(); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     return [Drawer, extendedApi as ExtendedDrawerApi] as const; |     return [Drawer, extendedApi as ExtendedDrawerApi] as const; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,16 @@ | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import type { ExtendedModalApi, ModalProps } from './modal'; | import type { ExtendedModalApi, ModalProps } from './modal'; | ||||||
| 
 | 
 | ||||||
| import { computed, nextTick, provide, ref, unref, useId, watch } from 'vue'; | import { | ||||||
|  |   computed, | ||||||
|  |   nextTick, | ||||||
|  |   onDeactivated, | ||||||
|  |   provide, | ||||||
|  |   ref, | ||||||
|  |   unref, | ||||||
|  |   useId, | ||||||
|  |   watch, | ||||||
|  | } from 'vue'; | ||||||
| 
 | 
 | ||||||
| import { | import { | ||||||
|   useIsMobile, |   useIsMobile, | ||||||
|  | @ -135,6 +144,16 @@ watch( | ||||||
| //   }, | //   }, | ||||||
| // ); | // ); | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * 在开启keepAlive情况下 直接通过浏览器按钮/手势等返回 不会关闭弹窗 | ||||||
|  |  */ | ||||||
|  | onDeactivated(() => { | ||||||
|  |   // 如果弹窗没有被挂载到内容区域,则关闭弹窗 | ||||||
|  |   if (!appendToMain.value) { | ||||||
|  |     props.modalApi?.close(); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| function handleFullscreen() { | function handleFullscreen() { | ||||||
|   props.modalApi?.setState((prev) => { |   props.modalApi?.setState((prev) => { | ||||||
|     // if (prev.fullscreen) { |     // if (prev.fullscreen) { | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ import { | ||||||
|   h, |   h, | ||||||
|   inject, |   inject, | ||||||
|   nextTick, |   nextTick, | ||||||
|   onDeactivated, |  | ||||||
|   provide, |   provide, | ||||||
|   reactive, |   reactive, | ||||||
|   ref, |   ref, | ||||||
|  | @ -71,13 +70,6 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>( | ||||||
|       }, |       }, | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 在开启keepAlive情况下 直接通过浏览器按钮/手势等返回 不会关闭弹窗 |  | ||||||
|      */ |  | ||||||
|     onDeactivated(() => { |  | ||||||
|       (extendedApi as ExtendedModalApi)?.close?.(); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     return [Modal, extendedApi as ExtendedModalApi] as const; |     return [Modal, extendedApi as ExtendedModalApi] as const; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -130,6 +122,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>( | ||||||
|     }, |     }, | ||||||
|   ); |   ); | ||||||
|   injectData.extendApi?.(extendedApi); |   injectData.extendApi?.(extendedApi); | ||||||
|  | 
 | ||||||
|   return [Modal, extendedApi] as const; |   return [Modal, extendedApi] as const; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,11 +3,11 @@ import type { Component } from 'vue'; | ||||||
| 
 | 
 | ||||||
| import type { AnyPromiseFunction } from '@vben/types'; | import type { AnyPromiseFunction } from '@vben/types'; | ||||||
| 
 | 
 | ||||||
| import { computed, ref, unref, useAttrs, watch } from 'vue'; | import { computed, nextTick, ref, unref, useAttrs, watch } from 'vue'; | ||||||
| 
 | 
 | ||||||
| import { LoaderCircle } from '@vben/icons'; | import { LoaderCircle } from '@vben/icons'; | ||||||
| 
 | 
 | ||||||
| import { get, isEqual, isFunction } from '@vben-core/shared/utils'; | import { cloneDeep, get, isEqual, isFunction } from '@vben-core/shared/utils'; | ||||||
| 
 | 
 | ||||||
| import { objectOmit } from '@vueuse/core'; | import { objectOmit } from '@vueuse/core'; | ||||||
| 
 | 
 | ||||||
|  | @ -104,6 +104,8 @@ const refOptions = ref<OptionsItem[]>([]); | ||||||
| const loading = ref(false); | const loading = ref(false); | ||||||
| // 首次是否加载过了 | // 首次是否加载过了 | ||||||
| const isFirstLoaded = ref(false); | const isFirstLoaded = ref(false); | ||||||
|  | // 标记是否有待处理的请求 | ||||||
|  | const hasPendingRequest = ref(false); | ||||||
| 
 | 
 | ||||||
| const getOptions = computed(() => { | const getOptions = computed(() => { | ||||||
|   const { labelField, valueField, childrenField, numberToString } = props; |   const { labelField, valueField, childrenField, numberToString } = props; | ||||||
|  | @ -146,18 +148,26 @@ const bindProps = computed(() => { | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| async function fetchApi() { | async function fetchApi() { | ||||||
|   let { api, beforeFetch, afterFetch, params, resultField } = props; |   const { api, beforeFetch, afterFetch, resultField } = props; | ||||||
| 
 | 
 | ||||||
|   if (!api || !isFunction(api) || loading.value) { |   if (!api || !isFunction(api)) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   // 如果正在加载,标记有待处理的请求并返回 | ||||||
|  |   if (loading.value) { | ||||||
|  |     hasPendingRequest.value = true; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   refOptions.value = []; |   refOptions.value = []; | ||||||
|   try { |   try { | ||||||
|     loading.value = true; |     loading.value = true; | ||||||
|  |     let finalParams = unref(mergedParams); | ||||||
|     if (beforeFetch && isFunction(beforeFetch)) { |     if (beforeFetch && isFunction(beforeFetch)) { | ||||||
|       params = (await beforeFetch(params)) || params; |       finalParams = (await beforeFetch(cloneDeep(finalParams))) || finalParams; | ||||||
|     } |     } | ||||||
|     let res = await api(params); |     let res = await api(finalParams); | ||||||
|     if (afterFetch && isFunction(afterFetch)) { |     if (afterFetch && isFunction(afterFetch)) { | ||||||
|       res = (await afterFetch(res)) || res; |       res = (await afterFetch(res)) || res; | ||||||
|     } |     } | ||||||
|  | @ -177,6 +187,13 @@ async function fetchApi() { | ||||||
|     isFirstLoaded.value = false; |     isFirstLoaded.value = false; | ||||||
|   } finally { |   } finally { | ||||||
|     loading.value = false; |     loading.value = false; | ||||||
|  |     // 如果有待处理的请求,立即触发新的请求 | ||||||
|  |     if (hasPendingRequest.value) { | ||||||
|  |       hasPendingRequest.value = false; | ||||||
|  |       // 使用 nextTick 确保状态更新完成后再触发新请求 | ||||||
|  |       await nextTick(); | ||||||
|  |       fetchApi(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -190,7 +207,7 @@ async function handleFetchForVisible(visible: boolean) { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const params = computed(() => { | const mergedParams = computed(() => { | ||||||
|   return { |   return { | ||||||
|     ...props.params, |     ...props.params, | ||||||
|     ...unref(innerParams), |     ...unref(innerParams), | ||||||
|  | @ -198,7 +215,7 @@ const params = computed(() => { | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| watch( | watch( | ||||||
|   params, |   mergedParams, | ||||||
|   (value, oldValue) => { |   (value, oldValue) => { | ||||||
|     if (isEqual(value, oldValue)) { |     if (isEqual(value, oldValue)) { | ||||||
|       return; |       return; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 xingyu4j
						xingyu4j