mirror of
https://github.com/jekip/naive-ui-admin.git
synced 2026-03-01 00:23:11 +08:00
fix: 修复在移动端模式下tags显示的bug update: 移动端模式下侧边菜单item点击隐藏drawer.
This commit is contained in:
@@ -8,6 +8,8 @@ export function useProjectSetting() {
|
|||||||
|
|
||||||
const getNavTheme = computed(() => projectStore.navTheme);
|
const getNavTheme = computed(() => projectStore.navTheme);
|
||||||
|
|
||||||
|
const getIsMobile = computed(() => projectStore.isMobile);
|
||||||
|
|
||||||
const getHeaderSetting = computed(() => projectStore.headerSetting);
|
const getHeaderSetting = computed(() => projectStore.headerSetting);
|
||||||
|
|
||||||
const getMultiTabsSetting = computed(() => projectStore.multiTabsSetting);
|
const getMultiTabsSetting = computed(() => projectStore.multiTabsSetting);
|
||||||
@@ -27,6 +29,7 @@ export function useProjectSetting() {
|
|||||||
return {
|
return {
|
||||||
getNavMode,
|
getNavMode,
|
||||||
getNavTheme,
|
getNavTheme,
|
||||||
|
getIsMobile,
|
||||||
getHeaderSetting,
|
getHeaderSetting,
|
||||||
getMultiTabsSetting,
|
getMultiTabsSetting,
|
||||||
getMenuSetting,
|
getMenuSetting,
|
||||||
|
|||||||
@@ -15,152 +15,153 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, onMounted, reactive, computed, watch, toRefs, unref } from 'vue';
|
import { defineComponent, ref, onMounted, reactive, computed, watch, toRefs, unref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
|
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
|
||||||
import { generatorMenu, generatorMenuMix } from '@/utils';
|
import { generatorMenu, generatorMenuMix } from '@/utils';
|
||||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Menu',
|
name: 'Menu',
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
mode: {
|
mode: {
|
||||||
// 菜单模式
|
// 菜单模式
|
||||||
type: String,
|
type: String,
|
||||||
default: 'vertical',
|
default: 'vertical',
|
||||||
},
|
|
||||||
collapsed: {
|
|
||||||
// 侧边栏菜单是否收起
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
//位置
|
|
||||||
location: {
|
|
||||||
type: String,
|
|
||||||
default: 'left',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
emits: ['update:collapsed'],
|
collapsed: {
|
||||||
setup(props, { emit }) {
|
// 侧边栏菜单是否收起
|
||||||
// 当前路由
|
type: Boolean,
|
||||||
const currentRoute = useRoute();
|
},
|
||||||
const router = useRouter();
|
//位置
|
||||||
const asyncRouteStore = useAsyncRouteStore();
|
location: {
|
||||||
const settingStore = useProjectSettingStore();
|
type: String,
|
||||||
const menus = ref<any[]>([]);
|
default: 'left',
|
||||||
const selectedKeys = ref<string>(currentRoute.name as string);
|
},
|
||||||
const headerMenuSelectKey = ref<string>('');
|
},
|
||||||
|
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({
|
const state = reactive({
|
||||||
openKeys: getOpenKeys,
|
openKeys: getOpenKeys,
|
||||||
});
|
});
|
||||||
|
|
||||||
const inverted = computed(() => {
|
const inverted = computed(() => {
|
||||||
return ['dark', 'header-dark'].includes(settingStore.navTheme);
|
return ['dark', 'header-dark'].includes(settingStore.navTheme);
|
||||||
});
|
});
|
||||||
|
|
||||||
const getSelectedKeys = computed(() => {
|
const getSelectedKeys = computed(() => {
|
||||||
let location = props.location;
|
let location = props.location;
|
||||||
return location === 'left' || (location === 'header' && unref(navMode) === 'horizontal')
|
return location === 'left' || (location === 'header' && unref(navMode) === 'horizontal')
|
||||||
? unref(selectedKeys)
|
? unref(selectedKeys)
|
||||||
: unref(headerMenuSelectKey);
|
: unref(headerMenuSelectKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听分割菜单
|
// 监听分割菜单
|
||||||
watch(
|
watch(
|
||||||
() => settingStore.menuSetting.mixMenu,
|
() => 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(() => {
|
|
||||||
updateMenu();
|
updateMenu();
|
||||||
});
|
if (props.collapsed) {
|
||||||
|
emit('update:collapsed', !props.collapsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
// 监听菜单收缩状态
|
||||||
...toRefs(state),
|
// watch(
|
||||||
inverted,
|
// () => props.collapsed,
|
||||||
menus,
|
// (newVal) => {
|
||||||
selectedKeys,
|
// }
|
||||||
headerMenuSelectKey,
|
// );
|
||||||
getSelectedKeys,
|
|
||||||
clickMenuItem,
|
// 跟随页面路由变化,切换菜单选中状态
|
||||||
menuExpanded,
|
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>
|
</script>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
|||||||
class="layout-side-drawer"
|
class="layout-side-drawer"
|
||||||
>
|
>
|
||||||
<Logo :collapsed="collapsed" />
|
<Logo :collapsed="collapsed" />
|
||||||
<AsideMenu />
|
<AsideMenu @clickMenuItem="collapsed = false" />
|
||||||
</n-drawer>
|
</n-drawer>
|
||||||
|
|
||||||
<n-layout :inverted="inverted">
|
<n-layout :inverted="inverted">
|
||||||
@@ -97,7 +97,10 @@ const collapsed = ref<boolean>(false);
|
|||||||
|
|
||||||
const { mobileWidth, menuWidth } = unref(getMenuSetting);
|
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 fixedHeader = computed(() => {
|
||||||
const { fixed } = unref(getHeaderSetting);
|
const { fixed } = unref(getHeaderSetting);
|
||||||
@@ -162,7 +165,6 @@ const showSideDrawder = computed({
|
|||||||
const checkMobileMode = () => {
|
const checkMobileMode = () => {
|
||||||
if (document.body.clientWidth <= mobileWidth) {
|
if (document.body.clientWidth <= mobileWidth) {
|
||||||
isMobile.value = true;
|
isMobile.value = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
isMobile.value = false;
|
isMobile.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ const setting = {
|
|||||||
navMode: 'vertical',
|
navMode: 'vertical',
|
||||||
//导航风格 dark 暗色侧边栏 light 白色侧边栏 header-dark 暗色顶栏
|
//导航风格 dark 暗色侧边栏 light 白色侧边栏 header-dark 暗色顶栏
|
||||||
navTheme: 'dark',
|
navTheme: 'dark',
|
||||||
|
// 是否处于移动端模式
|
||||||
|
isMobile: false,
|
||||||
//顶部
|
//顶部
|
||||||
headerSetting: {
|
headerSetting: {
|
||||||
//背景色
|
//背景色
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type { IheaderSetting, ImenuSetting, ImultiTabsSetting, IcrumbsSetting }
|
|||||||
const {
|
const {
|
||||||
navMode,
|
navMode,
|
||||||
navTheme,
|
navTheme,
|
||||||
|
isMobile,
|
||||||
headerSetting,
|
headerSetting,
|
||||||
showFooter,
|
showFooter,
|
||||||
menuSetting,
|
menuSetting,
|
||||||
@@ -27,6 +28,7 @@ interface ProjectSettingState {
|
|||||||
permissionMode: string; //权限模式
|
permissionMode: string; //权限模式
|
||||||
isPageAnimate: boolean; //是否开启路由动画
|
isPageAnimate: boolean; //是否开启路由动画
|
||||||
pageAnimateType: string; //路由动画类型
|
pageAnimateType: string; //路由动画类型
|
||||||
|
isMobile: boolean; // 是否处于移动端模式
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useProjectSettingStore = defineStore({
|
export const useProjectSettingStore = defineStore({
|
||||||
@@ -34,6 +36,7 @@ export const useProjectSettingStore = defineStore({
|
|||||||
state: (): ProjectSettingState => ({
|
state: (): ProjectSettingState => ({
|
||||||
navMode: navMode,
|
navMode: navMode,
|
||||||
navTheme,
|
navTheme,
|
||||||
|
isMobile,
|
||||||
headerSetting,
|
headerSetting,
|
||||||
showFooter,
|
showFooter,
|
||||||
menuSetting,
|
menuSetting,
|
||||||
@@ -50,6 +53,9 @@ export const useProjectSettingStore = defineStore({
|
|||||||
getNavTheme(): string {
|
getNavTheme(): string {
|
||||||
return this.navTheme;
|
return this.navTheme;
|
||||||
},
|
},
|
||||||
|
getIsMobile(): boolean {
|
||||||
|
return this.isMobile;
|
||||||
|
},
|
||||||
getHeaderSetting(): object {
|
getHeaderSetting(): object {
|
||||||
return this.headerSetting;
|
return this.headerSetting;
|
||||||
},
|
},
|
||||||
@@ -79,6 +85,9 @@ export const useProjectSettingStore = defineStore({
|
|||||||
setNavTheme(value: string): void {
|
setNavTheme(value: string): void {
|
||||||
this.navTheme = value;
|
this.navTheme = value;
|
||||||
},
|
},
|
||||||
|
setIsMobile(value: boolean): void {
|
||||||
|
this.isMobile = value;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user