Merge pull request #106 from MaybeQHL/main

fix: 修复在移动端模式下tags显示的bug  update: 移动端模式下侧边菜单item点击隐藏drawer.
This commit is contained in:
Ah jung
2022-03-08 08:42:29 +08:00
committed by GitHub
6 changed files with 702 additions and 678 deletions

View File

@@ -8,6 +8,8 @@ export function useProjectSetting() {
const getNavTheme = computed(() => projectStore.navTheme);
const getIsMobile = computed(() => projectStore.isMobile);
const getHeaderSetting = computed(() => projectStore.headerSetting);
const getMultiTabsSetting = computed(() => projectStore.multiTabsSetting);
@@ -27,6 +29,7 @@ export function useProjectSetting() {
return {
getNavMode,
getNavTheme,
getIsMobile,
getHeaderSetting,
getMultiTabsSetting,
getMenuSetting,

View File

@@ -15,152 +15,153 @@
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, reactive, computed, watch, toRefs, unref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
import { generatorMenu, generatorMenuMix } from '@/utils';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
import { defineComponent, ref, onMounted, reactive, computed, watch, toRefs, unref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
import { generatorMenu, generatorMenuMix } from '@/utils';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
export default defineComponent({
name: 'Menu',
components: {},
props: {
mode: {
// 菜单模式
type: String,
default: 'vertical',
},
collapsed: {
// 侧边栏菜单是否收起
type: Boolean,
},
//位置
location: {
type: String,
default: 'left',
},
export default defineComponent({
name: 'Menu',
components: {},
props: {
mode: {
// 菜单模式
type: String,
default: 'vertical',
},
emits: ['update:collapsed'],
setup(props, { emit }) {
// 当前路由
const currentRoute = useRoute();
const router = useRouter();
const asyncRouteStore = useAsyncRouteStore();
const settingStore = useProjectSettingStore();
const menus = ref<any[]>([]);
const selectedKeys = ref<string>(currentRoute.name as string);
const headerMenuSelectKey = ref<string>('');
collapsed: {
// 侧边栏菜单是否收起
type: Boolean,
},
//位置
location: {
type: String,
default: 'left',
},
},
emits: ['update:collapsed'],
setup(props, { emit }) {
// 当前路由
const currentRoute = useRoute();
const router = useRouter();
const asyncRouteStore = useAsyncRouteStore();
const settingStore = useProjectSettingStore();
const menus = ref<any[]>([]);
const selectedKeys = ref<string>(currentRoute.name as string);
const headerMenuSelectKey = ref<string>('');
const { getNavMode } = useProjectSetting();
const { getNavMode } = useProjectSetting();
const navMode = getNavMode;
const navMode = getNavMode;
// 获取当前打开的子菜单
const matched = currentRoute.matched;
// 获取当前打开的子菜单
const matched = currentRoute.matched;
const getOpenKeys = matched && matched.length ? matched.map((item) => item.name) : [];
const getOpenKeys = matched && matched.length ? matched.map((item) => item.name) : [];
const state = reactive({
openKeys: getOpenKeys,
});
const state = reactive({
openKeys: getOpenKeys,
});
const inverted = computed(() => {
return ['dark', 'header-dark'].includes(settingStore.navTheme);
});
const inverted = computed(() => {
return ['dark', 'header-dark'].includes(settingStore.navTheme);
});
const getSelectedKeys = computed(() => {
let location = props.location;
return location === 'left' || (location === 'header' && unref(navMode) === 'horizontal')
? unref(selectedKeys)
: unref(headerMenuSelectKey);
});
const getSelectedKeys = computed(() => {
let location = props.location;
return location === 'left' || (location === 'header' && unref(navMode) === 'horizontal')
? unref(selectedKeys)
: unref(headerMenuSelectKey);
});
// 监听分割菜单
watch(
() => settingStore.menuSetting.mixMenu,
() => {
updateMenu();
if (props.collapsed) {
emit('update:collapsed', !props.collapsed);
}
}
);
// 监听菜单收缩状态
// watch(
// () => props.collapsed,
// (newVal) => {
// }
// );
// 跟随页面路由变化,切换菜单选中状态
watch(
() => currentRoute.fullPath,
() => {
updateMenu();
const matched = currentRoute.matched;
state.openKeys = matched.map((item) => item.name);
const activeMenu: string = (currentRoute.meta?.activeMenu as string) || '';
selectedKeys.value = activeMenu ? (activeMenu as string) : (currentRoute.name as string);
}
);
function updateMenu() {
if (!settingStore.menuSetting.mixMenu) {
menus.value = generatorMenu(asyncRouteStore.getMenus);
} else {
//混合菜单
const firstRouteName: string = (currentRoute.matched[0].name as string) || '';
menus.value = generatorMenuMix(asyncRouteStore.getMenus, firstRouteName, props.location);
const activeMenu: string = currentRoute?.matched[0].meta?.activeMenu as string;
headerMenuSelectKey.value = (activeMenu ? activeMenu : firstRouteName) || '';
}
}
// 点击菜单
function clickMenuItem(key: string) {
if (/http(s)?:/.test(key)) {
window.open(key);
} else {
router.push({ name: key });
}
}
//展开菜单
function menuExpanded(openKeys: string[]) {
if (!openKeys) return;
const latestOpenKey = openKeys.find((key) => state.openKeys.indexOf(key) === -1);
const isExistChildren = findChildrenLen(latestOpenKey as string);
state.openKeys = isExistChildren ? (latestOpenKey ? [latestOpenKey] : []) : openKeys;
}
//查找是否存在子路由
function findChildrenLen(key: string) {
if (!key) return false;
const subRouteChildren: string[] = [];
for (const { children, key } of unref(menus)) {
if (children && children.length) {
subRouteChildren.push(key as string);
}
}
return subRouteChildren.includes(key);
}
onMounted(() => {
// 监听分割菜单
watch(
() => settingStore.menuSetting.mixMenu,
() => {
updateMenu();
});
if (props.collapsed) {
emit('update:collapsed', !props.collapsed);
}
}
);
return {
...toRefs(state),
inverted,
menus,
selectedKeys,
headerMenuSelectKey,
getSelectedKeys,
clickMenuItem,
menuExpanded,
};
},
});
// 监听菜单收缩状态
// watch(
// () => props.collapsed,
// (newVal) => {
// }
// );
// 跟随页面路由变化,切换菜单选中状态
watch(
() => currentRoute.fullPath,
() => {
updateMenu();
const matched = currentRoute.matched;
state.openKeys = matched.map((item) => item.name);
const activeMenu: string = (currentRoute.meta?.activeMenu as string) || '';
selectedKeys.value = activeMenu ? (activeMenu as string) : (currentRoute.name as string);
}
);
function updateMenu() {
if (!settingStore.menuSetting.mixMenu) {
menus.value = generatorMenu(asyncRouteStore.getMenus);
} else {
//混合菜单
const firstRouteName: string = (currentRoute.matched[0].name as string) || '';
menus.value = generatorMenuMix(asyncRouteStore.getMenus, firstRouteName, props.location);
const activeMenu: string = currentRoute?.matched[0].meta?.activeMenu as string;
headerMenuSelectKey.value = (activeMenu ? activeMenu : firstRouteName) || '';
}
}
// 点击菜单
function clickMenuItem(key: string) {
if (/http(s)?:/.test(key)) {
window.open(key);
} else {
router.push({ name: key });
}
emit("clickMenuItem" as any, key)
}
//展开菜单
function menuExpanded(openKeys: string[]) {
if (!openKeys) return;
const latestOpenKey = openKeys.find((key) => state.openKeys.indexOf(key) === -1);
const isExistChildren = findChildrenLen(latestOpenKey as string);
state.openKeys = isExistChildren ? (latestOpenKey ? [latestOpenKey] : []) : openKeys;
}
//查找是否存在子路由
function findChildrenLen(key: string) {
if (!key) return false;
const subRouteChildren: string[] = [];
for (const { children, key } of unref(menus)) {
if (children && children.length) {
subRouteChildren.push(key as string);
}
}
return subRouteChildren.includes(key);
}
onMounted(() => {
updateMenu();
});
return {
...toRefs(state),
inverted,
menus,
selectedKeys,
headerMenuSelectKey,
getSelectedKeys,
clickMenuItem,
menuExpanded,
};
},
});
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@
class="layout-side-drawer"
>
<Logo :collapsed="collapsed" />
<AsideMenu />
<AsideMenu @clickMenuItem="collapsed = false" />
</n-drawer>
<n-layout :inverted="inverted">
@@ -97,7 +97,10 @@ const collapsed = ref<boolean>(false);
const { mobileWidth, menuWidth } = unref(getMenuSetting);
const isMobile = ref<boolean>(false);
const isMobile = computed<boolean>({
get: () => settingStore.getIsMobile,
set: (val) => settingStore.setIsMobile(val)
});
const fixedHeader = computed(() => {
const { fixed } = unref(getHeaderSetting);
@@ -162,7 +165,6 @@ const showSideDrawder = computed({
const checkMobileMode = () => {
if (document.body.clientWidth <= mobileWidth) {
isMobile.value = true;
} else {
isMobile.value = false;
}

View File

@@ -3,6 +3,8 @@ const setting = {
navMode: 'vertical',
//导航风格 dark 暗色侧边栏 light 白色侧边栏 header-dark 暗色顶栏
navTheme: 'dark',
// 是否处于移动端模式
isMobile: false,
//顶部
headerSetting: {
//背景色

View File

@@ -6,6 +6,7 @@ import type { IheaderSetting, ImenuSetting, ImultiTabsSetting, IcrumbsSetting }
const {
navMode,
navTheme,
isMobile,
headerSetting,
showFooter,
menuSetting,
@@ -27,6 +28,7 @@ interface ProjectSettingState {
permissionMode: string; //权限模式
isPageAnimate: boolean; //是否开启路由动画
pageAnimateType: string; //路由动画类型
isMobile: boolean; // 是否处于移动端模式
}
export const useProjectSettingStore = defineStore({
@@ -34,6 +36,7 @@ export const useProjectSettingStore = defineStore({
state: (): ProjectSettingState => ({
navMode: navMode,
navTheme,
isMobile,
headerSetting,
showFooter,
menuSetting,
@@ -50,6 +53,9 @@ export const useProjectSettingStore = defineStore({
getNavTheme(): string {
return this.navTheme;
},
getIsMobile(): boolean {
return this.isMobile;
},
getHeaderSetting(): object {
return this.headerSetting;
},
@@ -79,6 +85,9 @@ export const useProjectSettingStore = defineStore({
setNavTheme(value: string): void {
this.navTheme = value;
},
setIsMobile(value: boolean): void {
this.isMobile = value;
},
},
});