接着之前的笔记,参考源码的布局,增加Sidebar的Logo组件及Navbar上折叠菜单的组件。
Sidebar上的Logo
先固定一个logo占位,默认为true.在src>layouts>Sidebar下新建Logo.vue。这里使用了VUE的内置组件
<template>
<div class="sidebar-logo-container" :class="{ collapse: collapse }">
<transition name="sidebarLogoFade">
<router-link
v-if="collapse"
key="collapse"
class="sidebar-logo-link"
to="/"
>
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title">{{ title }}</h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title">{{ title }}</h1>
</router-link>
</transition>
</div>
</template>
<script>
export default {
name: "SidebarLogo",
props: {
collapse: {
type: Boolean,
required: true
}
},
data() {
return {
title: "Vue Element Admin",
logo: "https://cn.vuejs.org/images/logo.png"
};
}
};
</script>
之后修改Sidebar的index.vue,将showLogo()方法暂时返回true.
Navbar
在vue-element-admin中,Navbar主要分为了8个部分
- hamburger 左侧菜单的折叠功能
- Breadcrumb 面包屑导航
- HeaderSearch 顶部的搜索
- Screenfull 全屏功能
- SizeSelect 布局大小
- LangSelect 语言选择
- Eldropdown 用户信息的下拉
hamburger
通过按钮,修改
其中vuex的app.js内容如下,暂时注释掉LangSelect的组件
import Cookies from "js-cookie";
// import { getLanguage } from '@/lang/index'
const state = {
sidebar: {
opened: Cookies.get("sidebarStatus")
? !!+Cookies.get("sidebarStatus")
: true,
withoutAnimation: false
},
device: "desktop",
language: "cn",
size: Cookies.get("size") || "medium"
};
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened;
state.sidebar.withoutAnimation = false;
if (state.sidebar.opened) {
Cookies.set("sidebarStatus", 1);
} else {
Cookies.set("sidebarStatus", 0);
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set("sidebarStatus", 0);
state.sidebar.opened = false;
state.sidebar.withoutAnimation = withoutAnimation;
},
TOGGLE_DEVICE: (state, device) => {
state.device = device;
},
SET_LANGUAGE: (state, language) => {
state.language = language;
Cookies.set("language", language);
},
SET_SIZE: (state, size) => {
state.size = size;
Cookies.set("size", size);
}
};
const actions = {
toggleSideBar({ commit }) {
commit("TOGGLE_SIDEBAR");
},
closeSideBar({ commit }, { withoutAnimation }) {
commit("CLOSE_SIDEBAR", withoutAnimation);
},
toggleDevice({ commit }, device) {
commit("TOGGLE_DEVICE", device);
},
setLanguage({ commit }, language) {
commit("SET_LANGUAGE", language);
},
setSize({ commit }, size) {
commit("SET_SIZE", size);
}
};
export default {
namespaced: true,
state,
mutations,
actions
};
在store的index.js和getter.js中配置相关的参数getter.js如下
const getters = {
roles: state => state.user.userInfo.roles,
permission_routes: state => state.permission.routes,
sidebar: state => state.app.sidebar,
language: state => state.app.language,
size: state => state.app.size,
device: state => state.app.device
};
export default getters;
在components下新建Hamburger>index.vue。通过传入的isActive属性来判断折叠按钮样式的变化。index.vue代码如下:
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{ 'is-active': isActive }"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path
d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
/>
</svg>
</div>
</template>
<script>
export default {
name: "Hamburger",
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit("toggleClick");
}
}
};
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>
在NavBar.vue中配置Hamburger组件,代码如下。其中store中的device用来移动端的自适应。而自适应使用了VUE的混入,源代码中为ResizeHandler.js。暂时不加进来。
<template>
<div class="navbar">
<hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import hamburger from "@/components/Hamburger";
export default {
components: { hamburger },
data() {
return {};
},
computed: {
...mapGetters(["sidebar", "avatar", "device"])
},
methods: {
toggleSideBar() {
this.$store.dispatch("app/toggleSideBar");
}
}
};
</script>
在添加后,折叠功能虽然可用,但折叠后SidebarItem的样式发生变化,之前sidebar的样式在lay>components>index.vue中import,通过阅读源码,发现全局样式进行了统一控制。导入源码中的样式配置,在src>styles中的index.scss,同时在main.js中导入全局配置。main.js添加内容如下。
import "@/styles/index.scss";
之后页面正常,但Item可能存在外链,所以修改SvgIcon组件,并做相关的判断。
VUE内置组件
到目前的学习中涉及到的内置组件有:
- transition 元素作为单个元素/组件的过渡效果。
只会把过渡效果应用到其包裹的内容上,而不会额外渲染 DOM 元素,也不会出现在可被检查的组件层级中。 - keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和
相似, 是一个抽象组件:它自身不会渲染一个DOM 元素,也不会出现在组件的父组件链中。当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。