其实是项目的导航栏组件。只打算看导航栏部分的可以跳过1.其他准备。
我们把它单独放到一个MenuData.js中,然后用export default
暴露出来。
{
path: '/',
name: 'home',
label: '首页',
icon: 's-home',
url: 'Home/Home'
},
{
path: '/mall',
name: 'mall',
label: '商品管理',
icon: 'video-play',
url: 'MallManage/MallManage'
},
{
path: '/user',
name: 'user',
label: '用户管理',
icon: 'user',
url: 'UserManage/UserManage'
},
{
label: '其他',
icon: 'location',
children: [
{
path: '/page1',
name: 'page1',
label: '页面1',
icon: 'setting',
url: 'Other/PageOne'
},
{
path: '/page2',
name: 'page2',
label: '页面2',
icon: 'setting',
url: 'Other/PageTwo'
}
]
}
注意要查看官方文档:官方文档
全局引入Element UI
先安装Element UI:
npm i element-ui -S
全局引入:在main.js中
import ElementUI from 'element-ui'
Vue.use(ElementUI)
路由配置
这里我们先配置Home页面(会显示导航栏的页面)。官方文档:Vue Router
安装:这里的版本是3.6.5
ps:可以在npm网站上查到包的所有版本,我们这里要的是3.x.x的最新版。
npm install vue-router@3.6.5
路由的配置:目前只配置了Main组件的
import Vue from "vue";
import VueRouter from "vue-router";
import Main from '../Views/Main'
Vue.use(VueRouter)
const routes=[
// 主路由
{
path:'/',
component:Main
}
]
const router = new VueRouter({
routes
})
export default router
目前的依赖
当前的package.json文件的dependencies应当如下:
"dependencies": {
"core-js": "^3.8.3",
"element-ui": "^2.15.10",
"vue": "^2.6.14",
"vue-router": "^3.6.5"
}
当前的main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
import router from './router/index'
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
router,
render: h => h(App),
}).$mount('#app')
<el-container>
<el-aside width="200px">Asideel-aside>
<el-container>
<el-header>Headerel-header>
<el-main>Mainel-main>
el-container>
el-container>
把它放到Main.vue里。
App.vue如下:
<template>
<div id="app">
<router-view>router-view>
div>
template>
<script>
export default {
}
script>
<style>
style>
效果:
接下来我们写一个组件:CommonAside.vue,把导航栏写在这个组件里,再把组件放到Aside中。
因此放了布局的Main.vue如下:
<template>
<el-container>
<el-aside width="200px">
<common-aside/>
el-aside>
<el-container>
<el-header>Headerel-header>
<el-main>Mainel-main>
el-container>
el-container>
template>
<script>
import CommonAside from '../components/CommonAside.vue'
export default {
data(){
return{}
},
components:{
CommonAside
}
}
script>
<style>
style>
组件CommonAside如下:
<template>
template>
<script>
export default {
}
script>
<style>
style>
接下来就是本文正题:导航栏。
Element UI文档
我们现在Element UI官方文档上找到类似的导航结构:就是你了!
阅读代码,我们不难发现代码分为“展开收起”部分和“导航”部分,我们要的是导航部分。把代码对着我们的目标稍作调整得到:
<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
:collapse="isCollapse">
<el-menu-item index="2">
<i class="el-icon-menu">i>
<span slot="title">导航一span>
el-menu-item>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location">i>
<span slot="title">导航二span>
template>
<el-menu-item-group>
<span slot="title">分组一span>
<el-menu-item index="1-1">选项1el-menu-item>
<el-menu-item index="1-2">选项2el-menu-item>
el-menu-item-group>
el-submenu>
el-menu>
导航栏分为一级导航栏和二级导航栏,目标中的 其他-页面1 就是二级导航栏,首页、商品管理、用户管理 都是一级导航栏。
一级和二级的区别在于:数据中是否有children属性,如果有,那它的children属性就是二级导航。所以这里要用到计算属性。
computed:{
noChildren(){
// 如果没有children则返回true,会被过滤器留下
return this.MenuData.filter(item=>!item.children)
},
hasChildren(){
return this.MenuData.filter(item=>item.children)
}
}
一级导航栏的循环显示:
<el-menu-item v-for="item in noChildren" :key="item.name" :index="item.name">
<i :class="`el-icon-${item.icon}`">i>
<span slot="title">{{item.label}}span>
el-menu-item>
<el-submenu v-for="item in hasChildren" :key="item.name" :index="item.name">
<template slot="title">
<i :class="`el-icon-${item.icon}`">i>
<span slot="title">{{item.label}}span>
template>
<el-menu-item-group v-for="subItem in item.children" :key="subItem.name">
<el-menu-item :index="subItem.name">{{subItem.label}}el-menu-item>
el-menu-item-group>
el-submenu>
el-menu>
再次打开文档,找到自定义颜色部分:
显然是这里:我们把它直接复制粘贴。
则标签如下:
<el-menu default-active="1-4-1"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
在浏览器中F12可知,padding是由body等标签自动带有的,我们只需要在App.vue中把它们清除即可(reset)。
html,
body,
h3,
p {
margin: 0;
padding: 0
}
这里我们先安装less:这样写CSS可以嵌套,更加方便。
npm install less less-loader --save
浏览器F12,显然有下拉框的这个类是:el-menu
把el-menu设置成height:100vh即可。
html:
<h3>通用后台管理系统h3>
css:
添加点击事件:
<el-menu-item
@click="clickItem(item)"
v-for="item in noChildren"
:key="item.name"
:index="item.name">
<el-menu-item-group
@click="clickItem(subItem)"
v-for="subItem in item.children"
:key="subItem.name">
js:
clickItem(item){
// 防止自己跳自己的报错
if(this.$route.path!==item.path&&!(this.$route.path==='/home'&&(item.path==='/'))){
this.$router.push(item.path)
}
}
不过目前只有一个路由。
<template>
<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
:collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
<h3>通用后台管理系统h3>
<el-menu-item @click="clickItem(item)" v-for="item in noChildren" :key="item.name" :index="item.name">
<i :class="`el-icon-${item.icon}`">i>
<span slot="title">{{ item.label }}span>
el-menu-item>
<el-submenu v-for="item in hasChildren" :key="item.name" :index="item.name">
<template slot="title">
<i :class="`el-icon-${item.icon}`">i>
<span slot="title">{{ item.label }}span>
template>
<el-menu-item-group @click="clickItem(subItem)" v-for="subItem in item.children" :key="subItem.name">
<el-menu-item :index="subItem.name">{{ subItem.label }}el-menu-item>
el-menu-item-group>
el-submenu>
el-menu>
template>
<style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
.el-menu{
height:100vh;
h3{
text-align: center;
line-height: 48px;
color: #fff;
font-size: 16px;
font-weight: 400;
}
}
style>
<script>
import MenuData from '../data/MenuData'
export default {
data() {
return {
isCollapse: false,
MenuData
};
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
clickItem(item){
// 防止自己跳自己的报错
if(this.$route.path!==item.path&&!(this.$route.path==='/home'&&(item.path==='/'))){
this.$router.push(item.path)
}
}
},
computed: {
noChildren() {
// 如果没有children则返回true,会被过滤器留下
return this.MenuData.filter(item => !item.children)
},
hasChildren() {
return this.MenuData.filter(item => item.children)
}
}
}
script>
VUE项目,VUE项目实战,vue后台管理系统,前端面试,前端面试项目