Vue + ElementUI 构建简单后台管理系统(登入首页+侧边菜单栏)

小虾米 阅读:608 2021-03-31 13:26:47 评论:0

最近帮助一位学弟编写一套简单的后台管理系统,我在网上找的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项目结构图:

 

标签:VUE
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号