From d48ab50fe22e441e46c5b989e0ba651b81bc08f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8E=E5=BF=83?= Date: Wed, 6 Aug 2025 16:53:16 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E9=80=82?= =?UTF-8?q?=E5=BA=94=E8=A1=A8=E6=A0=BC=E6=8C=87=E4=BB=A4[=E8=8B=A5?= =?UTF-8?q?=E9=87=87=E7=BA=B3=EF=BC=8C=E8=AF=B7=E5=B0=86=E5=85=B6=E4=BB=96?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=AE=8C=E5=96=84]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/RightToolbar/index.vue | 1 + src/directive/common/adaptive.ts | 74 +++++++++++++++++++++++++++ src/directive/index.ts | 2 + src/views/system/dept/index.vue | 1 + src/views/system/menu/index.vue | 5 +- src/views/system/post/index.vue | 3 +- src/views/system/user/index.vue | 9 ++-- 7 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 src/directive/common/adaptive.ts diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue index 02a55f7..899b074 100644 --- a/src/components/RightToolbar/index.vue +++ b/src/components/RightToolbar/index.vue @@ -53,6 +53,7 @@ const style = computed(() => { // 搜索 function toggleSearch() { emits('update:showSearch', !props.showSearch); + nextTick(() => window.dispatchEvent(new Event('resize'))); } // 刷新 diff --git a/src/directive/common/adaptive.ts b/src/directive/common/adaptive.ts new file mode 100644 index 0000000..d4472b3 --- /dev/null +++ b/src/directive/common/adaptive.ts @@ -0,0 +1,74 @@ +import type { Directive, DirectiveBinding } from 'vue'; + +// 扩展 HTMLElement 类型 +interface AdaptiveElement extends HTMLElement { + _resizeListener?: () => void; +} + +// 配置接口 +interface AdaptiveOptions { + height?: number; // 距离底部的距离,默认 90 +} + +const DEFAULT_HEIGHT = 105; + +/** + * 自适应高度指令 + * 用法: + *
+ *
+ */ +const vAdaptiveHeight: Directive = { + mounted(el, binding: DirectiveBinding) { + // 获取配置 + const config = binding.value || {}; + const bottomHeight = typeof config.height === 'number' ? config.height : DEFAULT_HEIGHT; + + // 设置高度 + const updateHeight = () => { + const rect = el.getBoundingClientRect(); + const top = rect.top; // 更准确 + const pageHeight = window.innerHeight; + el.style.height = `${pageHeight - top - bottomHeight}px`; + el.style.overflowY = 'auto'; + }; + + // 防抖:避免频繁触发 + let resizeTimer: number; + const onResize = () => { + clearTimeout(resizeTimer); + resizeTimer = window.setTimeout(() => { + requestAnimationFrame(updateHeight); + }, 100); + }; + + // 保存监听器,用于销毁 + el._resizeListener = onResize; + + // 初始设置 + updateHeight(); + + // 监听 resize + window.addEventListener('resize', onResize); + }, + + // 组件更新时重新计算(比如父组件 re-render) + updated(el, binding: DirectiveBinding) { + const config = binding.value || {}; + const bottomHeight = typeof config.height === 'number' ? config.height : DEFAULT_HEIGHT; + + const rect = el.getBoundingClientRect(); + const top = rect.top; + const pageHeight = window.innerHeight; + el.style.height = `${pageHeight - top - bottomHeight}px`; + }, + + unmounted(el) { + if (el._resizeListener) { + window.removeEventListener('resize', el._resizeListener); + delete el._resizeListener; + } + } +}; + +export default vAdaptiveHeight; diff --git a/src/directive/index.ts b/src/directive/index.ts index ef25ee8..8d660c9 100644 --- a/src/directive/index.ts +++ b/src/directive/index.ts @@ -1,9 +1,11 @@ import copyText from './common/copyText'; +import adaptive from './common/adaptive'; import { hasPermi, hasRoles } from './permission'; import { App } from 'vue'; export default (app: App) => { app.directive('copyText', copyText); + app.directive('adaptive', adaptive); app.directive('hasPermi', hasPermi); app.directive('hasRoles', hasRoles); }; diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index 56f4b17..28a0a5c 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -38,6 +38,7 @@ 新增 - 级联删除 + 级联删除 - + @@ -615,9 +616,7 @@ const handleUpdate = async (row?: UserForm) => { dialog.title = '修改用户'; Object.assign(form.value, data.user); postOptions.value = data.posts; - roleOptions.value = Array.from( - new Map([...data.roles, ...data.user.roles].map(role => [role.roleId, role])).values() - ); + roleOptions.value = Array.from(new Map([...data.roles, ...data.user.roles].map((role) => [role.roleId, role])).values()); form.value.postIds = data.postIds; form.value.roleIds = data.roleIds; form.value.password = ''; -- Gitee