5.6.3 • Published 6 months ago
@cimom/vben-effects-hooks v5.6.3
@cimom/vben-effects-hooks
用于多个 app 公用的 hook,继承了 @cimom/vben-core-composables 的所有能力,并扩展了更多业务场景下的钩子函数。业务上有通用 hooks 可以放在这里。
安装
# 进入目标应用目录,例如 apps/xxxx-app
# cd apps/xxxx-app
pnpm add @cimom/vben-effects-hooks可用钩子函数
useAppConfig - 应用配置钩子
用于获取应用的全局配置。
import { useAppConfig } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
console.log('API URL:', apiURL);useContentMaximize - 内容区域最大化钩子
用于控制内容区域的最大化状态。
import { useContentMaximize } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { isMaximized, toggleMaximize } = useContentMaximize();
// 切换最大化状态
function handleMaximizeClick() {
toggleMaximize();
}useDesignTokens - 设计令牌钩子
用于获取和使用设计系统的颜色、字体、间距等令牌。
import { useDesignTokens } from '@cimom/vben-effects-hooks';
// 在组件中使用
const {
primaryColor,
dangerColor,
successColor,
fontSizes,
spacing,
borderRadius,
} = useDesignTokens();
// 使用设计令牌
const buttonStyle = {
backgroundColor: primaryColor.value,
padding: `${spacing.value.sm} ${spacing.value.md}`,
borderRadius: borderRadius.value.sm,
fontSize: fontSizes.value.md,
};useHoverToggle - 悬停切换钩子
用于处理元素悬停状态的钩子函数。
import { useHoverToggle } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { isHovering, onMouseEnter, onMouseLeave } = useHoverToggle();
// 在模板中使用
// <div
// @mouseenter="onMouseEnter"
// @mouseleave="onMouseLeave"
// :class="{ 'hover-class': isHovering }"
// >
// 悬停内容
// </div>usePagination - 分页钩子
用于处理数组数据的分页。
import { ref } from 'vue';
import { usePagination } from '@cimom/vben-effects-hooks';
// 在组件中使用
const dataList = ref([
/* 大量数据项... */
]);
const {
paginationList, // 当前页数据
total, // 总数据量
setCurrentPage, // 设置当前页
setPageSize, // 设置每页条数
} = usePagination(dataList, 10); // 10 是每页条数
// 切换页码
function handlePageChange(page: number) {
setCurrentPage(page);
}
// 切换每页条数
function handlePageSizeChange(pageSize: number) {
setPageSize(pageSize);
}useRefresh - 刷新钩子
用于处理页面或组件的刷新逻辑。
import { useRefresh } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { refreshFlag, refreshPage } = useRefresh();
// 监听刷新标志变化
watch(refreshFlag, () => {
// 执行刷新逻辑
fetchData();
});
// 触发刷新
function handleRefresh() {
refreshPage();
}useTabs - 标签页钩子
用于管理标签页的状态和操作。
import { useTabs } from '@cimom/vben-effects-hooks';
// 在组件中使用
const {
tabs, // 标签页列表
activeTab, // 当前激活的标签页
addTab, // 添加标签页
removeTab, // 移除标签页
setActiveTab, // 设置激活的标签页
refreshTab, // 刷新标签页
} = useTabs();
// 添加新标签页
function handleAddTab(tab) {
addTab(tab);
}
// 关闭标签页
function handleCloseTab(tabKey) {
removeTab(tabKey);
}
// 切换标签页
function handleSwitchTab(tabKey) {
setActiveTab(tabKey);
}useWatermark - 水印钩子
用于在页面上添加和管理水印。
import { useWatermark } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { watermark, updateWatermark, destroyWatermark } = useWatermark();
// 初始化水印
onMounted(() => {
updateWatermark({
content: '机密文件 - 张三 2025-05-27',
fontSize: '16px',
globalAlpha: 0.15,
rotate: 30,
});
});
// 更新水印
function changeWatermark(text) {
updateWatermark({
content: text,
});
}
// 移除水印
function removeWatermark() {
destroyWatermark();
}
// 组件卸载时自动销毁水印
// onUnmounted(() => {
// destroyWatermark();
// });继承的核心钩子函数
该包继承了 @cimom/vben-core-composables 中的所有钩子函数,以下是一些常用的核心钩子:
useIsMobile - 移动设备检测
import { useIsMobile } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { isMobile } = useIsMobile();
// 根据设备类型调整布局
const layoutClass = computed(() => {
return isMobile.value ? 'mobile-layout' : 'desktop-layout';
});useLayoutStyle - 布局样式钩子
import { useLayoutStyle } from '@cimom/vben-effects-hooks';
// 在组件中使用
const { layoutStyle } = useLayoutStyle({
width: 1200,
height: 800,
top: 50,
left: 50,
});usePriorityValue - 优先级值钩子
import { usePriorityValue } from '@cimom/vben-effects-hooks';
// 在组件中使用
const propValue = ref('prop value');
const localValue = ref('local value');
const defaultValue = 'default value';
// 按优先级选择值:propValue > localValue > defaultValue
const value = usePriorityValue(propValue, localValue, defaultValue);useNamespace - 命名空间钩子
import { useNamespace } from '@cimom/vben-effects-hooks';
// 在组件中使用
const ns = useNamespace('button');
// 生成带命名空间的类名
const classes = computed(() => [
ns.b(), // 'vben-button'
ns.m('primary'), // 'vben-button--primary'
ns.e('label'), // 'vben-button__label'
ns.em('label', 'bold'), // 'vben-button__label--bold'
]);高级用法
组合多个钩子函数
import {
useIsMobile,
useDesignTokens,
useWatermark,
} from '@cimom/vben-effects-hooks';
// 在组件中组合使用多个钩子
const { isMobile } = useIsMobile();
const { primaryColor } = useDesignTokens();
const { updateWatermark } = useWatermark();
// 根据设备类型和主题设置水印
watchEffect(() => {
if (isMobile.value) {
// 移动设备上的水印配置
updateWatermark({
content: '移动版',
fontSize: '14px',
globalAlpha: 0.1,
});
} else {
// 桌面设备上的水印配置
updateWatermark({
content: '桌面版',
fontSize: '18px',
globalAlpha: 0.15,
advancedStyle: {
colorStops: [
{
color: primaryColor.value,
offset: 0,
},
{
color: primaryColor.value,
offset: 1,
},
],
type: 'linear',
},
});
}
});创建自定义钩子函数
import { ref, computed } from 'vue';
import { useIsMobile, useDesignTokens } from '@cimom/vben-effects-hooks';
// 创建自定义钩子函数
export function useResponsiveUI() {
const { isMobile } = useIsMobile();
const { spacing, fontSizes } = useDesignTokens();
// 响应式 UI 配置
const config = computed(() => {
if (isMobile.value) {
return {
fontSize: fontSizes.value.sm,
padding: spacing.value.xs,
columnCount: 1,
};
} else {
return {
fontSize: fontSizes.value.md,
padding: spacing.value.md,
columnCount: 3,
};
}
});
// 响应式类名
const classes = computed(() => {
return {
'mobile-ui': isMobile.value,
'desktop-ui': !isMobile.value,
};
});
return {
config,
classes,
isMobile,
};
}
// 在组件中使用自定义钩子
// const { config, classes } = useResponsiveUI();与其他包的集成
与 @cimom/vben-stores 集成
import { useUserStore } from '@cimom/vben-stores';
import { useWatermark } from '@cimom/vben-effects-hooks';
// 创建集成钩子
export function useUserWatermark() {
const userStore = useUserStore();
const { updateWatermark, destroyWatermark } = useWatermark();
// 监听用户信息变化,更新水印
watch(
() => userStore.userInfo,
(userInfo) => {
if (userInfo?.username) {
const now = new Date().toLocaleDateString();
updateWatermark({
content: `${userInfo.username} - ${now}`,
globalAlpha: 0.15,
});
} else {
destroyWatermark();
}
},
{ immediate: true },
);
return {
updateWatermark,
destroyWatermark,
};
}与 @cimom/vben-preferences 集成
import { usePreferences } from '@cimom/vben-preferences';
import { useDesignTokens } from '@cimom/vben-effects-hooks';
// 创建主题钩子
export function useThemeTokens() {
const { preferences } = usePreferences();
const designTokens = useDesignTokens();
// 根据用户偏好设置返回对应的设计令牌
const themeTokens = computed(() => {
const isDark = preferences.theme === 'dark';
return {
backgroundColor: isDark
? designTokens.darkBackground.value
: designTokens.lightBackground.value,
textColor: isDark
? designTokens.darkTextColor.value
: designTokens.lightTextColor.value,
// 其他主题相关令牌...
};
});
return themeTokens;
}注意事项
- 钩子函数应该在组件的
setup函数或<script setup>中调用,不应在普通函数中调用。 - 某些钩子函数(如
useWatermark)会在组件卸载时自动清理资源,无需手动处理。 - 使用
usePagination时,如果源数据列表发生变化,分页状态会自动更新。 - 响应式钩子返回的大多数值都是 Vue 的响应式对象(Ref 或 ComputedRef),使用时需要通过
.value访问实际值。
常见问题
钩子函数返回的值不是响应式的
确保正确使用了 .value 访问响应式对象的值:
// 错误用法
const { primaryColor } = useDesignTokens();
const style = { color: primaryColor }; // primaryColor 是 Ref,需要使用 .value
// 正确用法
const { primaryColor } = useDesignTokens();
const style = { color: primaryColor.value };
// 或者使用计算属性
const style = computed(() => ({ color: primaryColor.value }));水印不显示或显示异常
确保在调用 updateWatermark 时提供了正确的参数,并且在组件挂载后调用:
import { onMounted } from 'vue';
import { useWatermark } from '@cimom/vben-effects-hooks';
const { updateWatermark } = useWatermark();
onMounted(() => {
// 在组件挂载后初始化水印
updateWatermark({
content: '水印内容',
fontSize: '16px',
globalAlpha: 0.2, // 透明度 0-1
});
});分页钩子无法正确分页
确保提供给 usePagination 的数据列表是响应式的:
// 错误用法
const dataList = [
/* 数据项... */
]; // 非响应式数组
const { paginationList } = usePagination(dataList, 10);
// 正确用法
const dataList = ref([
/* 数据项... */
]); // 使用 ref 创建响应式数组
const { paginationList } = usePagination(dataList, 10);