primevue-mirror/layouts/AppMenu.vue

141 lines
5.5 KiB
Vue
Raw Normal View History

<template>
2022-09-14 14:26:41 +00:00
<div :class="['layout-sidebar', { active: active }]">
2022-09-10 14:29:14 +00:00
<nuxt-link to="/" class="logo">
2022-09-14 14:26:41 +00:00
<img :src="'/demo/images/primevue-logo-' + `${$appState.darkTheme ? 'light' : 'dark'}` + '.svg'" alt="primevue logo" />
2022-09-10 14:29:14 +00:00
</nuxt-link>
2022-02-23 11:42:11 +00:00
<div class="layout-sidebar-filter p-fluid">
2022-09-14 14:26:41 +00:00
<AutoComplete
v-model="selectedRoute"
:suggestions="filteredRoutes"
@complete="searchRoute($event)"
@item-select="onItemSelect($event)"
scrollHeight="300px"
placeholder="Search"
field="name"
optionGroupLabel="name"
optionGroupChildren="children"
appendTo="self"
>
2021-02-18 08:26:44 +00:00
</AutoComplete>
</div>
2018-12-06 19:23:02 +00:00
<div class="layout-menu">
2021-01-04 06:58:56 +00:00
<template v-for="item of menu" :key="item.name">
2021-07-12 07:52:22 +00:00
<div class="menu-category">
2022-09-14 14:26:41 +00:00
{{ item.name }}
2021-07-12 07:52:22 +00:00
<Tag v-if="item.badge" :value="item.badge"></Tag>
</div>
2021-08-05 13:14:06 +00:00
<div class="menu-items" v-if="item.children && item.children.length">
2021-01-04 06:58:56 +00:00
<template v-for="child of item.children" :key="child.name">
2022-09-14 14:26:41 +00:00
<a v-if="child.href" :href="child.href" target="_blank">{{ child.name }}</a>
2022-09-10 14:29:14 +00:00
<nuxt-link v-if="child.to" :to="child.to">
2022-09-14 14:26:41 +00:00
{{ child.name }}
2021-01-04 06:58:56 +00:00
<Tag v-if="child.badge" :value="child.badge"></Tag>
2022-09-10 14:29:14 +00:00
</nuxt-link>
2021-01-04 06:58:56 +00:00
<template v-if="child.children">
2022-09-14 14:26:41 +00:00
<nuxt-link :to="child.children[0].to" v-slot="{ isActive }" custom>
2021-01-04 06:58:56 +00:00
<div>
2021-02-10 10:49:36 +00:00
<a tabindex="0" @click="toggleSubmenu($event, child.meta[0])">
2022-09-14 14:26:41 +00:00
{{ child.name }}
2021-02-10 10:49:36 +00:00
<Tag v-if="child.badge" :value="child.badge"></Tag>
</a>
2021-01-04 06:58:56 +00:00
<transition name="p-toggleable-content">
<div class="p-toggleable-content" v-show="isSubmenuActive(child.meta[0], isActive)">
<ul>
<li v-for="(submenuitem, i) of child.children" :key="i">
2022-09-10 14:29:14 +00:00
<nuxt-link :to="submenuitem.to">
2022-09-14 14:26:41 +00:00
{{ submenuitem.name }}
2021-02-10 10:49:36 +00:00
<Tag v-if="submenuitem.badge" :value="submenuitem.badge"></Tag>
2022-09-10 14:29:14 +00:00
</nuxt-link>
2021-01-04 06:58:56 +00:00
</li>
</ul>
</div>
</transition>
</div>
2022-09-10 14:29:14 +00:00
</nuxt-link>
2021-01-04 06:58:56 +00:00
</template>
</template>
</div>
2021-07-27 08:59:25 +00:00
<div v-if="item.banner" class="menu-image">
<a :href="item.url">
2022-09-14 14:26:41 +00:00
<img :src="darkTheme ? item.imageDark : item.imageLight" />
2021-07-27 08:59:25 +00:00
</a>
</div>
2022-09-14 14:26:41 +00:00
</template>
2018-12-06 19:23:02 +00:00
</div>
</div>
</template>
<script>
2022-09-14 14:26:41 +00:00
import { FilterService, FilterMatchMode } from 'primevue/api';
2021-03-10 07:51:36 +00:00
import menudata from '@/assets/menu/menu.json';
2021-01-04 06:58:56 +00:00
export default {
2018-12-26 09:36:00 +00:00
props: {
2018-12-26 12:24:18 +00:00
active: Boolean
2018-12-26 09:36:00 +00:00
},
2018-12-06 19:23:02 +00:00
data() {
return {
2021-01-04 06:58:56 +00:00
activeSubmenus: {},
2021-03-10 07:51:36 +00:00
menu: menudata.data,
2021-02-18 08:26:44 +00:00
filteredRoutes: null,
selectedRoute: null,
routes: []
2022-09-14 14:26:41 +00:00
};
2018-12-06 19:23:02 +00:00
},
2021-01-04 06:58:56 +00:00
mounted() {
2021-03-10 07:51:36 +00:00
this.menu.forEach((route) => {
2022-09-14 14:26:41 +00:00
let childRoute = { ...route };
2021-03-10 07:51:36 +00:00
childRoute.children = childRoute.children.filter((child) => {
if (child.meta) {
this.routes.push(child);
}
2021-02-18 08:26:44 +00:00
2021-03-10 07:51:36 +00:00
return !child.meta;
2022-09-14 14:26:41 +00:00
});
2021-02-18 08:26:44 +00:00
2022-09-14 14:26:41 +00:00
this.routes.push(childRoute);
2021-03-10 07:51:36 +00:00
});
2021-01-04 06:58:56 +00:00
},
2018-12-06 19:23:02 +00:00
methods: {
2020-05-14 07:27:08 +00:00
toggleSubmenu(event, name) {
2022-09-14 14:26:41 +00:00
this.activeSubmenus[name] = this.activeSubmenus[name] ? false : true;
this.activeSubmenus = { ...this.activeSubmenus };
2020-05-14 07:27:08 +00:00
event.preventDefault();
2020-05-15 15:43:15 +00:00
},
isSubmenuActive(name, routerIsActive) {
2020-09-17 11:58:41 +00:00
if (this.activeSubmenus[name]) {
return true;
2022-09-14 14:26:41 +00:00
} else if (routerIsActive) {
2020-05-27 06:55:53 +00:00
this.activeSubmenus[name] = true;
return true;
}
return false;
2021-02-18 08:26:44 +00:00
},
searchRoute(event) {
let query = event.query;
let filteredRoutes = [];
for (let route of this.routes) {
let filteredItems = FilterService.filter(route.children, ['to', 'href'], query, FilterMatchMode.CONTAINS);
if (filteredItems && filteredItems.length) {
2022-09-14 14:26:41 +00:00
filteredRoutes.push({ name: route.name, children: filteredItems });
2021-02-18 08:26:44 +00:00
}
}
this.filteredRoutes = filteredRoutes;
},
onItemSelect(event) {
this.selectedRoute = null;
2022-09-14 14:26:41 +00:00
if (event.value.to) this.$router.push(event.value.to);
else if (event.value.href) window.location.href = event.value.href;
2018-12-06 19:23:02 +00:00
}
2021-07-27 08:59:25 +00:00
},
computed: {
darkTheme() {
return this.$appState.darkTheme === true;
}
2018-12-06 19:23:02 +00:00
}
2022-09-14 14:26:41 +00:00
};
2020-03-31 13:27:54 +00:00
</script>