经过前面的三节内容的准备工作,终于到了我们要实现页面的一节了。接下来我们要实现的是类似于下面的这种中后台的布局。让我们一步步来实现吧!
dashboard.vue
<template>
<div class="app-wrapper">
<div class="sidebar-container">
这是左边的导航
</div>
<div class="main-container">
<div class="nav-header">
这是导航部分
</div>
<div>
这是主体部分
</div>
</div>
</div>
</template>
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
display: flex;
.sidebar-container {
height: 100%;
border: 1px solid #ddd;
flex: 0 0 300px;
}
.main-container {
height: 100%;
border: 1px solid #ddd;
flex: 1;
.nav-header {
height: 80px;
border-bottom: 1px solid #ddd;
}
}
}
整体的架子就搭建出来了
接下来我们进一步的完善
如果在过程中遇到这种报错,不要急,我们来处理下
eslintrc
rules: {
...
'no-unused-vars': 'off'
}
就解决了
注意文件的层级关系,看上面的截图
logo.vue
<template>
<div class="sidebar-logo-container">
这是logo部分
</div>
</template>
sidebar/index.vue
<template>
<div>
<logo />
<el-scrollbar wrap-class="scrollbar-wrapper">siderbar</el-scrollbar>
</div>
</template>
<script>
import Logo from './Logo'
export default {
components: {
Logo
}
}
</script>
<style lang="scss" scoped></style>
src/layout/components/index.js
// 不懂的可以参考这里https://es6.ruanyifeng.com/#docs/module#export-%E4%B8%8E-import-%E7%9A%84%E5%A4%8D%E5%90%88%E5%86%99%E6%B3%95
export { default as Sidebar } from './Sidebar/index.vue'
左侧的导航就出来了,样子虽然有点丑,我们继续进行美化
完善我们的Logo.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>
import Logo from '@/assets/images/logo.png'
export default {
name: 'SidebarLogo',
props: {
collapse: {
type: Boolean,
require: true
}
},
data() {
return {
title: 'GLADMIN后台管理系统',
logo: Logo
}
}
}
</script>
<style lang="scss" scoped>
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
overflow: hidden;
.sidebar-logo-link {
height: 100%;
width: 100%;
.sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 6px;
}
.sidebar-title {
display: inline-block;
color: #000;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0px;
}
}
}
</style>
Siderbar.vue
<logo :collapse="false" />
测试效果
Siderbar.vue
<logo :collapse="true" />
测试效果
根据组件上的这个collapse收起和展开的属性动态显示隐藏网站名字,并且还加入了动画过渡,暂时看不到效果,等我们加入切换按钮就能感知到了。
接下来暂时不想做sidebar的菜单,趁着现在collapse的出现,我们来实现这个折叠的功能!实现绿色的按钮点击显示隐藏左边的sidebar
新建src/layout/components/Sidebar/Navbar.vue文件
<template>
<div class="navbar">
<hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
</div>
</template>
<script>
export default {
methods: {
toggleSideBar() {}
}
}
</script>
<style lang="scss" scoped></style>
我们暂时不关注后面的面包屑,只实现toggleSideBar功能
src/layout/components/Sidebar/Logo.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>
import Logo from '@/assets/images/logo.png'
export default {
name: 'SidebarLogo',
props: {
collapse: {
type: Boolean,
require: true
}
},
data() {
return {
title: 'GLADMIN后台管理系统',
logo: Logo
}
}
}
</script>
<style lang="scss" scoped>
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
overflow: hidden;
.sidebar-logo-link {
height: 100%;
width: 100%;
.sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 6px;
}
.sidebar-title {
display: inline-block;
color: #000;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0px;
}
}
}
</style>
src/layout/components/Sidebar/index.vue
<template>
<div>
<logo :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">siderbar</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
export default {
components: {
Logo
},
computed: {
...mapGetters(['sidebar']),
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>
<style lang="scss" scoped></style>
src/layout/components/Navbar/index.vue
<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 '@comps/Hamburger'
export default {
computed: {
...mapGetters(['sidebar'])
},
components: {
Hamburger
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
}
}
}
</script>
<style lang="scss" scoped>
.navbar {
height: 50px;
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
}
</style>
src/store/modules/app.js
yarn add js-cookie -S
import Cookies from 'js-cookie'
const app = {
namespaced: true, // 开启命名空间
state: {
sidebar: {
opened: Cookies.get('sidebarStatus')
? !!+Cookies.get('sidebarStatus')
: true,
withoutAnimation: false
}
},
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
}
},
actions: {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
}
}
}
export default app
经过以上一些列 操作后我们实现了
至此我们的切换功能就实现了,剩下的就是左侧的elementuil里面的nav导航进行收缩和隐藏了!实现起来就容易了