Vue + ElementUI 构建简单后台管理系统(登入首页+侧边菜单栏)
最近帮助一位学弟编写一套简单的后台管理系统,我在网上找的Vue模板发现需要改很多地方,而且那些模板也没有写代码的实现思路,对于我这种vue项目经验不是很足的人有些难以读懂,所以就按照自己的思路从零实现一遍,过程讲解基本算详细的,若是有不足之处还请指正。
整体后台管理系统效果:
登入首页
菜单
Vue 项目
新建Vue 项目(seven)
#创建一个基于webpack模板的新项目
vue init webpack D:\node_workspace\seven
# 切换至项目路径
cd d:D:\node_workspace\seven
# 安装项目依赖文件
cnpm install
# 项目启动
cnpm run dev
安装element-ui
# 切换至项目路径
cd d:D:\node_workspace\seven
# 安装element-ui
cnpm i element-ui -S
编辑Vue项目(seven)的main.js ,添加如下代码片段:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
安装axios
# 切换至项目路径
cd d:D:\node_workspace\seven
# 安装axios
cnpm i axios -S
编辑Vue项目(seven)的main.js ,添加如下代码片段:
import axios from '../node_modules/axios'
# 设置后端请求地址
axios.defaults.baseURL='http://localhost:9097/api'
Vue.prototype.$axios = axios
Vue项目(seven)的main.js 文件:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import axios from '../node_modules/axios'
Vue.config.productionTip = false
Vue.use(ElementUI);
// 设置后端请求地址
axios.defaults.baseURL='http://localhost:9091/api'
Vue.prototype.$axios = axios
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
编写登入组件Login.vue
在VUE项目(seven)中,新建views文件夹,新增Login.vue 组件
<template>
<div class="login-wrap">
<el-form
class="login-form"
label-position="top"
label-width="80px"
:model="formdata"
>
<h2>用户登录</h2>
<el-form-item label="用户名">
<el-input v-model="formdata.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formdata.password"></el-input>
</el-form-item>
<el-button class="login-btn" type="primary" @click="handleLodin()">登录</el-button>
</el-form>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
formdata: {
username: "",
password: "",
},
};
},
methods:{
handleLodin(){
//测试版本
if(this.formdata.username !== '' && this.formdata.password !== ''){
this.$router.push({path:'/home'})
// 2.提示成功
this.$message({
showClose: true,
message: '登录成功',
type: 'success'
});
}else {
this.$message({
showClose: true,
message: '用户名和密码不能为空',
type: 'error'
});
}
}
}
};
</script>
<style scoped>
.login-wrap {
height: 100%;
background: #324152;
display: flex;
justify-content: center;
align-items: center;
}
.login-form {
width: 400px;
background: #fff;
border-radius: 5px;
padding: 30px;
}
.login-btn {
width: 100%;
}
</style>
说明:1、登入页使用el-form表单进行布局,label-position="top"表示表单域标签的位置是上下对齐,:model="formdata"表示我们要绑定的数据。
2、当用户点击登录按钮的时候会触发handleclick事件,然后发送axios请求,如果登录成功就跳转到下一个页面,显示登录成功的提示消息,如果失败就抛出错误提示消息。
渲染效果:
编写Home组件Home.vue
第一步:布局分为三部分,头部header,侧边栏aside,右边主体,用elementui布局如下
<template>
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: 'Home'
};
</script>
效果截图:
第二步:页面样式美好
<template>
<el-container class="container">
<el-header class="header">
header
</el-header>
<el-container>
<el-aside class="aside">
<!-- 侧边栏导航 -->
aside
</el-aside>
<el-main class="main">Main</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: "Home"
};
</script>
<style scoped>
.container {
height: 100vh;
font-size: 15px;
}
.header {
background: #212121;
color: #fff;
}
.aside {
background: #3a3a3a;
color: #fff;
/* height: 100%; */
}
.main {
/* height: 100%; */
color: #212121;
}</style>
效果截图:
第三步:头部样式布局
通过24分栏进行布局。将头部分为两部分,左边占16栏,右边占8栏el-row表示一行,el-col表示列。
<el-row>
<el-col :span="16" class="headerlogo">
<div class="grid-content bg-purple">
<img
style="width:400px;height: 30px"
src="../../assets/img/top.png"
alt="无法显示图片"
/>
</div>
</el-col>
<el-col :span="8" class="rightsection">
<div class="grid-content bg-purple-light">
<span class="el-dropdown-link userinfo-inner">欢迎您,管理员</span>
<span class="userinfo-inner" @click="signout">退出</span>
</div>
</el-col>
</el-row>
效果截图:
第三步:侧边栏菜单样式布局
在elementui中用el-menu标签实现侧边栏菜单布局。
其中el-menu定义了当前的导航菜单及属性,el-submenu定义了子菜单栏,el-menu-item-group定义了菜单分组,el-menu-item为具体的菜单项,组件从上到下分别是:el-menu, el-submenu, el-menu-item-group, el-menu-item。
下面这段代码拷贝之Element官网,https://element.eleme.cn/#/zh-CN/component/menu
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
第四步:头部样式布局 + 侧边栏菜单样式布局 合并效果
<template>
<el-container class="container">
<el-header class="header">
<el-row>
<el-col :span="16" class="headerlogo">
<div class="grid-content bg-purple">
<img
style="width:400px;height: 30px"
src="../../assets/img/top.png"
alt="无法显示图片"
/>
</div>
</el-col>
<el-col :span="8" class="rightsection">
<div class="grid-content bg-purple-light">
<span class="el-dropdown-link userinfo-inner">欢迎您,管理员</span>
<span class="userinfo-inner" @click="signout">退出</span>
</div>
</el-col>
</el-row>
</el-header>
<el-container>
<el-aside class="aside">
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main class="main">Main</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: "Home",
methods: {
//退出
signout() {
this.$confirm("退出登录, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
this.$router.push({ path: "/" });
});
},
},
};
</script>
<style scoped>
.container {
height: 100vh;
font-size: 15px;
}
.header {
background: #212121;
color: #fff;
}
.aside {
background: #3a3a3a;
color: #fff;
/* height: 100%; */
}
.main {
/* height: 100%; */
color: #212121;
}
.headerlogo {
line-height: 60px;
margin-top: 10px;
}
.rightsection {
line-height: 60px;
text-align: center;
}
</style>
效果展示:
第五步:动态菜单渲染
v-for循环显示menuData
<el-aside class="aside">
<!-- 侧边栏导航 -->
<!-- unique-opened只展开一个 -->
<!-- router开启路由模式 -->
<el-menu :unique-opened="true" :router="true" class="menu"
background-color=" #3A3A3A"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-submenu :index="' '+item1.order" v-for="(item1,index) in menuData" :key="item1.path">
<!--表示可以展开的一组 -->
<template slot="title" @click="clickTitle">
<!--图标 -->
<i class="el-icon-location"></i>
<!--文字 -->
<span>{
{item1.name}}</span>
</template>
<el-menu-item
class="menuItem"
@click="clickMenuItem"
v-for="(item2,index) in item1.children"
:key="item2.path"
:index="item2.path"
>
<i class="el-icon-location"></i>
<!--图标 -->
<span>{
{item2.name}}</span>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
重点说明:
- el-submenu之 index属性: 这个index表示每一组的唯一标志,当我们定义了 unique-opened=true的时候会根据这个标识展示相应的选项。自己可以测试一下把所有的选项组的index都设置成同一个值得时候是什么效果就明白了这个标志得作用。
- el-menu-item 之index属性:这个index值会被作为跳转路径进行跳转,我们需要把这个值和页面路径对应起来。所以需要开启路由模式,点击那个页面的时候左侧就会显示哪个页面内容信息。
定义模拟动态渲染菜单数据:
data() {
return {
style: {
display: "block",
},
menuData: [
{
name: "学生管理",
order: "1",
path:'studentmanage',
children: [
{
path: "studentmanage",
name: "学生信息",
},
],
},
{
path: "mealcardmanage",
name: "饭卡管理",
order: "2",
children: [
{
path: "mealcardmanage",
name: "饭卡信息",
},
],
},
{
path: "devicemanage",
name: "设备终端管理",
order: "3",
children: [
{
path: "devicemanage",
name: "设备终端信息",
},
],
},
{
path: "customermanager",
name: "消费管理",
order: "4",
children: [
{
path: "customermanager",
name: "消费信息",
},
],
},
{
path: "adminmanager",
name: "管理员",
order: "5",
children: [
{
path: "adminmanager",
name: "管理员信息",
},
],
},
],
};
},
注意,menuData中的path要和路由跳转的path相同,不然跳转的时候会找不到对应的页面。
第六步:路由地址绑定(route/index.js)
el-menu-item 中的index会替换成我们实际需要跳转的路径
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = () => import('../views/Home.vue')
const Login = () => import('../views/Login.vue')
const StudentManage = () => import('../views/StudentManage.vue')
const MealCardManage = () => import('../views/MealCardManage.vue')
const DeviceManage = () => import('../views/DeviceManage.vue')
const AdminManager = () => import('../views/AdminManager.vue')
const CustomerManager = () => import('../views/CustomerManager.vue')
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Login',
component: Login
},
{
path: '/home',
name: 'Home',
component: Home,
children:[
{
path: '/studentmanage',
name: '学生信息',
component: StudentManage,
},{
path: '/mealcardmanage',
name: '饭卡信息',
component: MealCardManage,
},{
path: '/devicemanage',
name: '设备终端信息',
component: DeviceManage,
},{
path: '/customermanager',
name: '消费信息',
component: CustomerManager,
},{
path: '/adminmanager',
name: '管理员信息',
component: AdminManager,
}]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
第七步:其他组件编写
StudentManage.vue
<template>
<div>学生信息页面</div>
</template>
<script>
export default {
name: 'StudentManage'
}
</script>
MealCardManage.vue
<template>
<div>饭卡信息页面</div>
</template>
<script>
export default {
name: 'MealCardManage'
}
</script>
DeviceManage.vue
<template>
<div>终端设备信息页面</div>
</template>
<script>
export default {
name: 'DeviceManage'
}
</script>
AdminManager.vue
<template>
<div>管理员信息页面</div>
</template>
<script>
export default {
name: 'AdminManager'
}
</script>
CustomerManager.vue
<template>
<div>消费记录信息页面</div>
</template>
<script>
export default {
name: 'CustomerManager'
}
</script>
整体效果截图:
Vue项目结构图:
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。