docs_vue2/components/OneMenu.vue

272 lines
5.2 KiB
Vue
Raw Normal View History

2020-08-13 11:47:56 +08:00
<template>
2022-06-14 09:05:00 +08:00
<nav v-outside="collapseMenu" class="one-nav" :class="{ expanded }">
<header>
<h2>{{ Config.app_name }}</h2>
<section class="search">
<one-search />
</section>
<div class="toggle" @click="toggleMenu">
<veui-icon class="expanded-icon" name="chevron-left" />
<veui-icon class="collapsed-icon" name="hamburger" />
</div>
</header>
<veui-menu
class="one-menu"
:items="menuItems"
:expanded.sync="menuExpanded"
2022-04-26 15:45:48 +08:00
>
2022-06-14 09:05:00 +08:00
<template #item-label="{ label, sub }">
{{ label }}<small>{{ sub }}</small>
</template>
</veui-menu>
</nav>
2020-08-13 11:47:56 +08:00
</template>
<script>
2022-06-14 09:05:00 +08:00
import i18n from "../common/i18n";
import OneSearch from "./OneSearch";
import { Menu, Icon } from "veui";
import outside from "veui/directives/outside";
import "veui-theme-dls-icons/hamburger";
import "veui-theme-dls-icons/chevron-left";
import Config from "../env";
2020-08-13 11:47:56 +08:00
export default {
2022-06-14 09:05:00 +08:00
name: "one-menu",
directives: {
2022-06-14 09:05:00 +08:00
outside,
},
components: {
2022-06-14 09:05:00 +08:00
"one-search": OneSearch,
"veui-menu": Menu,
"veui-icon": Icon,
},
2020-08-13 11:47:56 +08:00
mixins: [i18n],
props: {
expanded: Boolean,
2020-08-13 11:47:56 +08:00
nav: {
type: Array,
2022-06-14 09:05:00 +08:00
default() {
return [];
},
},
2020-08-13 11:47:56 +08:00
},
2022-06-14 09:05:00 +08:00
data() {
return {
2022-06-14 09:05:00 +08:00
Config,
menuExpanded: [],
};
},
2020-08-13 11:47:56 +08:00
computed: {
2022-06-14 09:05:00 +08:00
altLocale() {
let { canonicalPath, locale, getLocalePath, isPathDisabled } = this;
let altLocale = locale === "zh-Hans" ? "en-US" : "zh-Hans";
let label = locale === "zh-Hans" ? "English" : "中文";
let disabled = isPathDisabled(canonicalPath, altLocale);
2020-08-13 11:47:56 +08:00
return {
2022-06-14 09:05:00 +08:00
to: disabled ? "" : getLocalePath(canonicalPath, altLocale),
2020-08-13 11:47:56 +08:00
disabled,
2022-06-14 09:05:00 +08:00
label,
};
},
menuItems() {
return this.nav.map((item) => this.normalizeItem(item));
},
2020-08-13 11:47:56 +08:00
},
2022-06-14 09:05:00 +08:00
created() {
this.menuExpanded = this.menuItems.map(({ name }) => name);
2020-08-13 11:47:56 +08:00
},
methods: {
2022-06-14 09:05:00 +08:00
getTitleDetail(title) {
let [main, sub] = title.split(" - ");
return [main, sub];
2020-08-13 11:47:56 +08:00
},
2022-06-14 09:05:00 +08:00
isActive(path) {
let { route = {} } = this.$router.resolve(path) || {};
return route.name === this.$route.name;
2020-08-13 11:47:56 +08:00
},
2022-06-14 09:05:00 +08:00
normalizeItem({ title, children, slug, link, disabled }, base = "") {
const fullSlug = `${base}/${slug}`;
const localePath = this.getLocalePath(fullSlug);
const to = link !== false && fullSlug && !disabled ? localePath : null;
const [main, sub] = this.getTitleDetail(title);
2020-08-13 11:47:56 +08:00
return {
label: main,
sub,
to,
name: fullSlug,
disabled,
2022-06-14 09:05:00 +08:00
children: children
? children.map((child) => this.normalizeItem(child, fullSlug))
: [],
};
},
2022-06-14 09:05:00 +08:00
toggleMenu() {
this.$emit("toggle", !this.expanded);
},
2022-06-14 09:05:00 +08:00
collapseMenu() {
this.$emit("toggle", false);
},
},
};
2020-08-13 11:47:56 +08:00
</script>
<style lang="stylus" scoped>
2022-06-14 09:05:00 +08:00
.one-nav {
position: fixed;
top: 0;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
width: 280px;
z-index: 1;
background-color: #fff;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
header {
padding: 32px 20px 20px;
flex: none;
}
2021-08-23 19:37:43 +08:00
2022-06-14 09:05:00 +08:00
h2 {
display: flex;
align-items: center;
margin: 0 0 16px;
font-size: 20px;
font-weight: 500;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
a {
display: block;
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
& + .desc {
display: flex;
align-items: center;
margin-bottom: 20px;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
img {
display: block;
}
}
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.locale-swith {
display: block;
margin-left: 12px;
padding: 0 6px;
border: 1px solid #dbdbdb;
border-radius: 3px;
line-height: 18px;
font-size: 12px;
text-align: center;
text-decoration: none;
transition: all 0.2s;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
&:hover {
border-color: #999;
}
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.search {
margin-top: 16px;
margin-right: 12px;
flex-shrink: 0;
}
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.one-menu {
flex: 1 1 auto;
width: 100%;
overflow: auto;
background-color: #fff;
2022-04-26 15:45:48 +08:00
2022-06-14 09:05:00 +08:00
& >>> .DocSearch {
margin: 0;
border-radius: 6px;
font: inherit;
}
2022-04-26 15:45:48 +08:00
2022-06-14 09:05:00 +08:00
small {
margin-left: 8px;
opacity: 0.7;
}
}
2022-04-26 15:45:48 +08:00
2022-06-14 09:05:00 +08:00
.toggle {
display: none;
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.disabled {
opacity: 0.3;
pointer-events: none;
}
2022-06-14 09:05:00 +08:00
@media (max-width: 480px) {
.one-nav {
z-index: 20;
transition: transform 0.3s, box-shadow 0.3s;
transform: translateX(-100%);
2022-06-14 09:05:00 +08:00
&.expanded {
transform: translateX(0);
box-shadow: 0 0 48px rgba(0, 0, 0, 0.2);
}
}
2022-06-14 09:05:00 +08:00
header {
position: relative;
}
2022-06-14 09:05:00 +08:00
.toggle {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
position: absolute;
top: 80px;
left: 100%;
border: 1px solid #e2e6f0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
background-color: #fff;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.1);
font-size: 20px;
2022-06-14 09:05:00 +08:00
&::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: -19px;
width: 20px;
background-color: #fff;
}
}
}
2021-10-22 13:01:41 +08:00
2022-06-14 09:05:00 +08:00
.expanded-icon, .collapsed-icon {
position: absolute;
transition: transform 0.3s, opacity 0.3s;
}
2021-10-22 13:01:41 +08:00
2022-06-14 09:05:00 +08:00
.expanded-icon {
margin-left: -4px;
opacity: 0;
transform: translateX(-10px);
2021-10-22 13:01:41 +08:00
2022-06-14 09:05:00 +08:00
.expanded & {
opacity: 1;
transform: none;
}
}
2021-10-22 13:01:41 +08:00
2022-06-14 09:05:00 +08:00
.collapsed-icon {
.expanded & {
opacity: 0;
transform: translateX(10px);
}
}
2020-08-13 11:47:56 +08:00
</style>