Vue + ElementUI 构建简单后台管理系统(登入首页+侧边菜单栏)
2022-08-03 09:57:03
202
{{single.collect_count}}

最近帮助一位学弟编写一套简单的后台管理系统,我在网上找的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-uicnpm 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# 安装axioscnpm 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 = falseVue.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-formclass="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"><imgstyle="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-menudefault-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"><imgstyle="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-menudefault-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-itemclass="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项目结构图:

 

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}