feat(projects): 添加判断是否是移动端的hooks

This commit is contained in:
Soybean 2021-11-14 22:16:44 +08:00
parent 1a76de0446
commit 0a9fba90b5
13 changed files with 56 additions and 34 deletions

View File

@ -7,6 +7,7 @@ import useRouteProps from './useRouteProps';
import useBoolean from './useBoolean'; import useBoolean from './useBoolean';
import useLoading from './useLoading'; import useLoading from './useLoading';
import useScrollBehavior from './useScrollBehavior'; import useScrollBehavior from './useScrollBehavior';
import useIsMobile from './useIsMobile';
export { export {
useAppTitle, useAppTitle,
@ -17,5 +18,6 @@ export {
useRouteProps, useRouteProps,
useBoolean, useBoolean,
useLoading, useLoading,
useScrollBehavior useScrollBehavior,
useIsMobile
}; };

View File

@ -0,0 +1,11 @@
import { useBreakpoints, breakpointsTailwind } from '@vueuse/core';
/** 是否是移动端 */
export default function useIsMobile() {
const breakpoints = useBreakpoints(breakpointsTailwind);
const isMobile = breakpoints.smaller('lg');
return {
isMobile
};
}

View File

@ -72,8 +72,6 @@ interface MenuStyle {
mixWidth: number; mixWidth: number;
/** 混合菜单折叠时的宽度 */ /** 混合菜单折叠时的宽度 */
mixCollapsedWidth: number; mixCollapsedWidth: number;
/** 分割菜单 */
splitMenu: boolean;
/** 水平模式的菜单的位置 */ /** 水平模式的菜单的位置 */
horizontalPosition: HorizontalMenuPosition; horizontalPosition: HorizontalMenuPosition;
/** 水平模式的菜单的位置列表 */ /** 水平模式的菜单的位置列表 */

View File

@ -4,7 +4,7 @@
:class="{ 'overflow-hidden': routeProps.fullPage }" :class="{ 'overflow-hidden': routeProps.fullPage }"
> >
<router-view v-slot="{ Component, route }"> <router-view v-slot="{ Component, route }">
<transition :name="theme.pageStyle.animateType" mode="out-in" appear> <transition :name="theme.pageAnimateType" mode="out-in" appear>
<keep-alive :include="cacheRoutes"> <keep-alive :include="cacheRoutes">
<component :is="Component" v-if="reload" :key="route.fullPath" class="flex-1" /> <component :is="Component" v-if="reload" :key="route.fullPath" class="flex-1" />
</keep-alive> </keep-alive>

View File

@ -1,9 +1,6 @@
<template> <template>
<n-divider title-placement="center">界面功能</n-divider> <n-divider title-placement="center">界面功能</n-divider>
<n-space vertical size="large"> <n-space vertical size="large">
<setting-menu-item label="分割菜单">
<n-switch :value="theme.menuStyle.splitMenu" @update:value="handleSplitMenu" />
</setting-menu-item>
<setting-menu-item label="顶部菜单位置"> <setting-menu-item label="顶部菜单位置">
<n-select <n-select
class="w-120px" class="w-120px"
@ -34,7 +31,7 @@
/> />
</setting-menu-item> </setting-menu-item>
<setting-menu-item label="固定头部和多页签"> <setting-menu-item label="固定头部和多页签">
<n-switch :value="splitMenu" :disabled="disabledSplitMenu" @update:value="handleFixedHeaderAndTab" /> <n-switch :value="theme.fixedHeaderAndTab" :disabled="isHorizontalMix" @update:value="handleFixedHeaderAndTab" />
</setting-menu-item> </setting-menu-item>
<setting-menu-item label="头部高度"> <setting-menu-item label="头部高度">
<n-input-number <n-input-number
@ -65,7 +62,6 @@ import { SettingMenuItem } from '../common';
const theme = useThemeStore(); const theme = useThemeStore();
const { const {
handleSplitMenu,
handleHorizontalMenuPosition, handleHorizontalMenuPosition,
handleFixedHeaderAndTab, handleFixedHeaderAndTab,
handleHeaderHeight, handleHeaderHeight,
@ -74,8 +70,7 @@ const {
handleMixMenuWidth handleMixMenuWidth
} = useThemeStore(); } = useThemeStore();
const disabledSplitMenu = computed(() => theme.navStyle.mode === 'horizontal-mix'); const isHorizontalMix = computed(() => theme.navStyle.mode === 'horizontal-mix');
const splitMenu = computed(() => theme.fixedHeaderAndTab || disabledSplitMenu.value);
const disabledMenuWidth = computed(() => { const disabledMenuWidth = computed(() => {
const { mode } = theme.navStyle; const { mode } = theme.navStyle;
return mode !== 'vertical' && mode !== 'horizontal-mix'; return mode !== 'vertical' && mode !== 'horizontal-mix';

View File

@ -2,7 +2,7 @@
<n-scrollbar ref="scrollbar" class="h-full" :x-scrollable="true" :content-class="routeProps.fullPage ? 'h-full' : ''"> <n-scrollbar ref="scrollbar" class="h-full" :x-scrollable="true" :content-class="routeProps.fullPage ? 'h-full' : ''">
<div class="inline-block wh-full bg-[#F6F9F8]"> <div class="inline-block wh-full bg-[#F6F9F8]">
<router-view v-slot="{ Component, route: itemRoute }"> <router-view v-slot="{ Component, route: itemRoute }">
<transition :name="theme.pageStyle.animateType" mode="out-in" appear> <transition :name="theme.pageAnimateType" mode="out-in" appear>
<keep-alive :include="cacheRoutes"> <keep-alive :include="cacheRoutes">
<component <component
:is="Component" :is="Component"

View File

@ -3,9 +3,14 @@ import App from './App.vue';
import AppProvider from './AppProvider.vue'; import AppProvider from './AppProvider.vue';
import { setupStore } from './store'; import { setupStore } from './store';
import { setupRouter } from './router'; import { setupRouter } from './router';
import { setupWindicssDarkMode } from './plugins'; import { setupAssets, setupWindicssDarkMode } from './plugins';
import 'virtual:windi.css';
import './styles/css/global.css'; function setupPlugins() {
/** 引入静态资源 */
setupAssets();
// 配置windicss暗黑主题
setupWindicssDarkMode();
}
async function setupApp() { async function setupApp() {
const appProvider = createApp(AppProvider); const appProvider = createApp(AppProvider);
@ -22,9 +27,7 @@ async function setupApp() {
// 路由准备就绪后挂载APP实例 // 路由准备就绪后挂载APP实例
app.mount('#app', true); app.mount('#app', true);
// 配置windicss暗黑主题
setupWindicssDarkMode();
} }
setupPlugins();
setupApp(); setupApp();

5
src/plugins/assets.ts Normal file
View File

@ -0,0 +1,5 @@
import 'virtual:windi.css';
import '../styles/css/global.css';
/** 引入静态资源 */
export default function setupAssets() {}

View File

@ -7,15 +7,19 @@ export default function setupWindicssDarkMode() {
const DARK_CLASS = 'dark'; const DARK_CLASS = 'dark';
function getHtmlElement() { function getHtmlElement() {
return document.querySelector('html')!; return document.querySelector('html');
} }
function addDarkClass() { function addDarkClass() {
const html = getHtmlElement(); const html = getHtmlElement();
html.classList.add(DARK_CLASS); if (html) {
html.classList.add(DARK_CLASS);
}
} }
function removeDarkClass() { function removeDarkClass() {
const html = getHtmlElement(); const html = getHtmlElement();
html.classList.remove(DARK_CLASS); if (html) {
html.classList.remove(DARK_CLASS);
}
} }
watch( watch(
@ -26,6 +30,7 @@ export default function setupWindicssDarkMode() {
} else { } else {
removeDarkClass(); removeDarkClass();
} }
} },
{ immediate: true }
); );
} }

View File

@ -1,3 +1,4 @@
import setupAssets from './assets';
import setupWindicssDarkMode from './dark-mode'; import setupWindicssDarkMode from './dark-mode';
export { setupWindicssDarkMode }; export { setupAssets, setupWindicssDarkMode };

View File

@ -36,7 +36,6 @@
"collapsedWidth": 64, "collapsedWidth": 64,
"mixWidth": 80, "mixWidth": 80,
"mixCollapsedWidth": 48, "mixCollapsedWidth": 48,
"splitMenu": false,
"horizontalPosition": "flex-start", "horizontalPosition": "flex-start",
"horizontalPositionList": [ "horizontalPositionList": [
{ {

View File

@ -42,7 +42,6 @@ const defaultThemeSettings: ThemeSettings = {
collapsedWidth: 64, collapsedWidth: 64,
mixWidth: 80, mixWidth: 80,
mixCollapsedWidth: 48, mixCollapsedWidth: 48,
splitMenu: false,
horizontalPosition: 'flex-start', horizontalPosition: 'flex-start',
horizontalPositionList: [ horizontalPositionList: [
{ value: 'flex-start', label: EnumHorizontalMenuPosition['flex-start'] }, { value: 'flex-start', label: EnumHorizontalMenuPosition['flex-start'] },

View File

@ -33,6 +33,11 @@ const themeStore = defineStore({
const { hover: warningColorHover, pressed: warningColorPressed } = getHoverAndPressedColor(warningColor); const { hover: warningColorHover, pressed: warningColorPressed } = getHoverAndPressedColor(warningColor);
const { hover: errorColorHover, pressed: errorColorPressed } = getHoverAndPressedColor(errorColor); const { hover: errorColorHover, pressed: errorColorPressed } = getHoverAndPressedColor(errorColor);
const primaryColorSuppl = primaryColor;
const infoColorSuppl = infoColor;
const successColorSuppl = infoColor;
const warningColorSuppl = warningColor;
const errorColorSuppl = errorColor;
const colorLoading = primaryColor; const colorLoading = primaryColor;
return { return {
@ -40,23 +45,23 @@ const themeStore = defineStore({
primaryColor, primaryColor,
primaryColorHover, primaryColorHover,
primaryColorPressed, primaryColorPressed,
primaryColorSuppl: primaryColor, primaryColorSuppl,
infoColor, infoColor,
infoColorHover, infoColorHover,
infoColorPressed, infoColorPressed,
infoColorSuppl: infoColor, infoColorSuppl,
successColor, successColor,
successColorHover, successColorHover,
successColorPressed, successColorPressed,
successColorSuppl: infoColor, successColorSuppl,
warningColor, warningColor,
warningColorHover, warningColorHover,
warningColorPressed, warningColorPressed,
warningColorSuppl: warningColor, warningColorSuppl,
errorColor, errorColor,
errorColorHover, errorColorHover,
errorColorPressed, errorColorPressed,
errorColorSuppl: errorColor errorColorSuppl
}, },
LoadingBar: { LoadingBar: {
colorLoading colorLoading
@ -73,6 +78,9 @@ const themeStore = defineStore({
isVerticalNav(): boolean { isVerticalNav(): boolean {
const { mode } = this.navStyle; const { mode } = this.navStyle;
return mode === 'vertical' || mode === 'vertical-mix'; return mode === 'vertical' || mode === 'vertical-mix';
},
pageAnimateType(): AnimateType | '' {
return this.pageStyle.animate ? this.pageStyle.animateType : '';
} }
}, },
actions: { actions: {
@ -92,10 +100,6 @@ const themeStore = defineStore({
setNavMode(mode: NavMode) { setNavMode(mode: NavMode) {
this.navStyle.mode = mode; this.navStyle.mode = mode;
}, },
/** 切割菜单(顶部混合模式horizontal-mix) */
handleSplitMenu(isSplit: boolean) {
this.menuStyle.splitMenu = isSplit;
},
/** 更改菜单展开的宽度 */ /** 更改菜单展开的宽度 */
handleMenuWidth(width: number | null) { handleMenuWidth(width: number | null) {
if (width !== null) { if (width !== null) {