【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面

文章目录

  • 0. 项目介绍
    • 电商管理系统(Element-UI)
    • 开发模式
    • 前端技术栈
    • 后端技术栈
  • 1. 配置——初始化 前端项目
    • ① 安装 Vue 脚手架
    • ② 通过 Vue 脚手架创建项目
    • ③ 配置 Vue 路由
    • ④ 配置 Element-UI 组件库
    • ⑤ 配置 axios 库
    • ⑥ 语法处理ESLint
    • ⑦ 初始化 git 远程仓库
    • ⑧ 将本地项目托管到 Github 或 码云 中
  • 2. 配置后端接口
    • ① 安装 MySQL 数据库
    • ② 安装 Node.js 环境
    • ③ 配置项目相关信息
    • ④ 启动项目
    • ⑤查看API文档电商管理后台 API 接口文档.md
    • ⑥ 使用 Postman 测试后台项目接口是否正常
  • 3. 登录/退出功能
    • 3.1 登录业务流程
    • 3.2 登录业务的相关技术点
    • 3.3 token原理
    • 3.4 登录功能实现
      • 3.4.1 布局分析
      • 3.4.2 Git 创建login分支
      • 3.4.3 渲染Login组件并实现路由重定向
      • 3.4.4 设置背景颜色并在屏幕中央绘制登录盒子
      • 3.4.5 绘制默认头像
      • 3.4.6 绘制登录表单区域
      • 3.4.7 绘制带icon的input输入框
      • 3.4.8 实现表单的数据绑定
      • 3.4.9 实现表单的数据验证
      • 3.4.10 实现表单的重置功能
      • 3.4.11 实现登录前表单数据的预验证,配置axios发起登录请求
      • 3.4.12 路由导航守卫控制页面访问权限
    • 3.5 效果展示
    • 3.6 退出功能实现
      • 3.6.1 退出功能实现原理
      • 3.6.2 具体操作
    • 3.7 Login 完整代码
    • 3.8 将本地代码提交到码云Gitee中
  • 4. 主页布局
    • 4.1 整体布局
    • 4.2 美化主页Header区域
    • 4.3 实现左侧导航菜单的基本结构
    • 4.4 通过axios拦截器添加token验证
    • 4.5 获取左侧菜单数据
    • 4.6 通过双层for循环渲染左侧菜单
    • 4.7 为选中项设置字体颜色并添加分类图标
    • 4.8 每次只能打开一个菜单项并解决边框问题
    • 4.9 实现侧边栏的折叠与展开效果
    • 4.10 实现首页路由的重定向效果
    • 4.11 实现侧边栏路由链接的改造
    • 4.12 Home完整代码
  • 5. 展示

项目地址https://gitee.com/ykang2020/vue_shop

0. 项目介绍

电商管理系统(Element-UI)

电商后台管理系统用于管理用户账号、商品分类、商品信息、订单、数据统计等业务功能
【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第1张图片

开发模式

电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是基于 Vue 技术栈的 SPA(单页应用程序) 项目
【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第2张图片

前端技术栈

  • Vue
  • Vue-router
  • Element-UI
  • Axios
  • Echarts

后端技术栈

  • Node.js
  • Express
  • Jwt(模拟session)
  • Mysql
  • Sequelize(操作数据库的框架)

1. 配置——初始化 前端项目

① 安装 Vue 脚手架

② 通过 Vue 脚手架创建项目

③ 配置 Vue 路由

④ 配置 Element-UI 组件库

⑤ 配置 axios 库

⑥ 语法处理ESLint

⑦ 初始化 git 远程仓库

⑧ 将本地项目托管到 Github 或 码云 中

详见【Vue】vue-cli - 图形化创建项目 - 配置项目 - axios - elementUI - 码云SSH公钥设置 - Gitee同步

2. 配置后端接口

① 安装 MySQL 数据库

  1. 使用phpStudy软件(关闭Apache)
    【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第3张图片
  2. 导入数据库文件(路径不能有中文)
    【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第4张图片
  3. 检查数据 里面有数据说明导入完成
    【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第5张图片

② 安装 Node.js 环境

③ 配置项目相关信息

cd E:\YKcode\web\myProject01\api\vue_api_server
cnpm install

④ 启动项目

出错了就多 npm installcnpm install 几下

node app.js

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第6张图片

⑤查看API文档电商管理后台 API 接口文档.md

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210314154316727.png?x-oss-process=image/waterma【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第7张图片

⑥ 使用 Postman 测试后台项目接口是否正常

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第8张图片
根据文档测试
【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第9张图片
调试成功
【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第10张图片

3. 登录/退出功能

3.1 登录业务流程

① 在登录页面输入用户名和密码
② 调用后台接口进行验证
③ 通过验证之后,根据后台的响应状态跳转到项目主页

3.2 登录业务的相关技术点

  • http 是无状态的 (stateless)(不保存通信状态)
  • 通过 cookie 在客户端记录状态 (前端与后端没有跨域问题使用)
  • 通过 session 在服务器端记录状态 (前端与后端没有跨域问题使用)
  • 通过 token 方式维持状态 (有跨域问题时使用)

相关参考【彻底理解cookie,session,token - 墨颜丶 - 博客园】

3.3 token原理

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第11张图片

3.4 登录功能实现

3.4.1 布局分析

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第12张图片
通过 Element-UI 组件实现布局

  • el-form
  • el-form-item
  • el-input
  • el-button
  • 字体图标

3.4.2 Git 创建login分支

创建分支

git checkout -b login

查看分支

git branch

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第13张图片

3.4.3 渲染Login组件并实现路由重定向

  1. 清空Vue模板和路由 main.js App.vue ./components/HelloWorld.vue ./views
  2. 创建组件 ./view/Login.vue
  3. 添加路由规则 ./router/index.js 设置默认页面重定向到login
import Login from '../components/Login.vue'
const routes = [
  {
      path: '/', redirect: '/login' },
  {
      path: '/login', component: Login }
]
  1. 添加路由占位符 App.vue
  <div id="app">
    
    <router-view>router-view>
  div>

3.4.4 设置背景颜色并在屏幕中央绘制登录盒子

  1. 在可视化工具中安装 开发依赖 less 和 less-loader
  2. 安装过依赖后要重新编译
  3. 设置全局样式 ./assets/css/global.css
/* 全局样式表 */
html,
body,
#app {
     
  height: 100%;
  margin: 0;
  padding: 0;
  min-width: 1366px;
}
  1. 入口文件导入全局css文件 ./main.js
// 导入全局样式表
import './assets/css/global.css'
  1. 设置背景颜色并在屏幕中央绘制登录盒子 Login.vue
<div class="login_container">
  <div class="login_box">div>
div>
.login_container {
     
  background-color: #409eff;
  height: 100%;
}

.login_box {
     
  width: 450px;
  height: 300px;
  background-color: #fff;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

3.4.5 绘制默认头像


<div class="avatar_box">
  <img src="../assets/YK.jpg" alt="" />
div>
.avatar_box {
     
  height: 130px;
  width: 130px;
  border: 1px solid #eee;
  border-radius: 50%;
  padding: 10px;
  box-shadow: 0 0 10px #ddd;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
}
img {
     
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #eee;
}

3.4.6 绘制登录表单区域

  1. 按需导入用到的element组件 ./plugins/element.js
import Vue from 'vue'
import {
      Button, Form, FormItem, Input } from 'element-ui'
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
  1. 页面使用引入的组件标签 Login.vue

<el-form label-width="0px" class="login_form">
  
  <el-form-item>
    <el-input>el-input>
  el-form-item>
  
  <el-form-item>
    <el-input>el-input>
  el-form-item>
  
  <el-form-item>
    <el-button type="primary" class="btns">登录el-button>
    <el-button type="info">重置el-button>
  el-form-item>
el-form>
.login_form {
     
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}
.btns {
     
  display: flex;
  justify-content: flex-end;
}

3.4.7 绘制带icon的input输入框

https://element.eleme.cn/#/zh-CN/component/input
官方图标库 https://element.eleme.cn/#/zh-CN/component/icon

<el-input prefix-icon="el-icon-user">el-input>
<el-input prefix-icon="el-icon-lock">el-input>
  • 阿里字体图标库的使用
  1. 下载选好的阿里字体图标
  2. demo_fontclass.html查看图标名称
  3. 引入iconfont.css样式表 import './assets/fonts/iconfont.css'
  4. 标签添加类名 class=“iconfont icon-xxx”

3.4.8 实现表单的数据绑定

<el-form :model="loginForm">
	<el-input v-model="loginForm.username">el-input>
	<el-input v-model="loginForm.password" type="password">el-input>
el-form>
export default {
     
  data () {
     
    return {
     
      // 这是登录表单的数据绑定对象
      loginForm: {
     
        username: 'admin',
        password: '123456'
      }
    }
  }
}

3.4.9 实现表单的数据验证

<el-form :rules="loginFormRules">
	<el-form-item prop="username">
		<el-input v-model="loginForm.username">el-input>
	el-form-item>
	<el-form-item prop="password">
		<el-input v-model="loginForm.password" type="password">el-input>
	el-form-item>
el-form>
export default {
     
  data () {
     
    return {
     
	  loginFormRules: {
     
	    // 验证用户名是否合法
	    username: [
	      {
      required: true, message: '请输入登录名称', trigger: 'blur' },
	      {
      min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
	    ],
	    // 验证密码是否合法
	    password: [
	      {
      required: true, message: '请输入登录密码', trigger: 'blur' },
	      {
      min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
	    ]
	  }
	}
  }
}

3.4.10 实现表单的重置功能

  1. 添加引用ref获取表单实例对象(通过 ref 标注 DOM 元素)
<el-form ref="loginFormRef">el-form>
  1. 重置按钮绑定单击事件
<el-button type="info" @click="resetLoginForm">重置el-button>
  1. 定义重置方法(通过 $refs 获取 DOM 元素)
methods: {
     
  // 点击重置按钮,重置登录表单
  resetLoginForm () {
     
    // console.log(this) // VueComponent
    this.$refs.loginFormRef.resetFields()
  }
}

3.4.11 实现登录前表单数据的预验证,配置axios发起登录请求

  1. 添加点击事件
<el-button type="primary" @click="login">登录el-button>
  1. 导入axios包main.js,配置axios
import axios from 'axios'
// 配置请求的根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
Vue.prototype.$http = axios
  1. 导入弹框提示组件element.js
import {
      Message } from 'element-ui'
Vue.prototype.$message = Message // 弹框提示组件挂在在Vue原型上
  1. 编写login方法
methods: {
     
  login () {
     
    this.$refs.loginFormRef.validate(async (valid) => {
     
      // console.log(valid) // false/ture
      if (!valid) return
      const {
      data: result } = await this.$http.post('login', this.loginForm)
      // console.log(result) //Promise
      if (result.meta.status !== 200) return this.$message.error('登录失败')
      this.$message.success('登录成功')
      
      // 1. 将登录成功之后的 token 保存到客户端的 sessionStorage 中(会话期间的存储机制)(所以不放在loaclStorage中)
      window.sessionStorage.setItem('token', result.data.token)
      // 2. 通过编程式导航跳转到后台主页,路由地址是 /home
      this.$router.push('/home')
    })
  }
}
  1. 编写Home.vue并导入路由规则
import Home from '../components/Home.vue'
const routes = [  
  {
      path: '/home', component: Home, }
]

3.4.12 路由导航守卫控制页面访问权限

如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面
router/index.js

// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
     
  // to 将要访问的路径
  // from 代表从哪个路径跳转而来
  // next 是一个函数, 表示放行   ①next()放行   ②next('/login')强制跳转
  if (to.path === '/login') return next() // 访问登录页,直接放行
  // 获取token
  const tokenStr = window.sessionStorage.getItem('token')
  if (!tokenStr) return next('/login') // 没有token 强制跳转
  next() // 否则(有token)直接放行
})

3.5 效果展示

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第14张图片

3.6 退出功能实现

3.6.1 退出功能实现原理

基于token的方式实现退出比较简单,只需要销毁本地的token即可。
这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才可以访问页面

3.6.2 具体操作

<el-button type="info" @click="logout">退出el-button>
methods: {
     
  logout() {
     
    window.sessionStorage.clear()
    this.$router.push('/login')
  }
}

3.7 Login 完整代码

<template>
  <div class="login_container">
    <div class="login_box">
      
      <div class="avatar_box">
        <img src="../assets/YK.jpg" alt="" />
      div>
      
      <el-form
        ref="loginFormRef"
        :model="loginForm"
        :rules="loginFormRules"
        label-width="0px"
        class="login_form"
      >
        
        <el-form-item prop="username">
          <el-input
            prefix-icon="el-icon-user"
            v-model="loginForm.username"
          >el-input>
        el-form-item>
        
        <el-form-item prop="password">
          <el-input
            prefix-icon="el-icon-lock"
            v-model="loginForm.password"
            type="password"
          >el-input>
        el-form-item>
        
        <el-form-item class="btns">
          <el-button type="primary" @click="login">登录el-button>
          <el-button type="info" @click="resetLoginForm">重置el-button>
        el-form-item>
      el-form>
    div>
  div>
template>

<script>
export default {
      
  data () {
      
    return {
      
      // 这是登录表单的数据绑定对象
      loginForm: {
      
        username: 'admin',
        password: '123456'
      },
      // 这是表单验证规则对象
      loginFormRules: {
      
        // 验证用户名是否合法
        username: [
          {
       required: true, message: '请输入登录名称', trigger: 'blur' },
          {
       min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
        ],
        // 验证密码是否合法
        password: [
          {
       required: true, message: '请输入登录密码', trigger: 'blur' },
          {
      
            min: 6,
            max: 15,
            message: '长度在 6 到 15 个字符',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  methods: {
      
    // 点击重置按钮,重置登录表单
    resetLoginForm () {
      
      // console.log(this) // VueComponent
      this.$refs.loginFormRef.resetFields()
    },
    login () {
      
      this.$refs.loginFormRef.validate(async (valid) => {
      
        // console.log(valid) // false/ture
        if (!valid) return
        const {
       data: result } = await this.$http.post('login', this.loginForm)
        // console.log(result)
        if (result.meta.status !== 200) return this.$message.error('登录失败')
        this.$message.success('登录成功')
        // 将登录成功之后的token 保存到客户端的 sessionStorage 中(会话期间的存储机制)(所以不放在loaclStorage中)
        console.log(result)
        window.sessionStorage.setItem('token', result.data.token)
        // 通过编程式导航跳转到后台主页,路由地址是 /home
        this.$router.push('/home')
      })
    }
  }
}
script>

<style scoped>
.login_container {
      
  background-color: #409eff;
  height: 100%;
}

.login_box {
      
  width: 450px;
  height: 300px;
  background-color: #fff;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.avatar_box {
      
  height: 130px;
  width: 130px;
  border: 1px solid #eee;
  border-radius: 50%;
  padding: 10px;
  box-shadow: 0 0 10px #ddd;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
}

img {
      
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #eee;
}

.login_form {
      
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}

.btns {
      
  display: flex;
  justify-content: flex-end;
}
style>

3.8 将本地代码提交到码云Gitee中

  1. 查看文件状态
git status
  1. 代码添加到缓存区
git add .
  1. 提交到本地库
git commit -m "完成了登录功能"
  1. 查看分支
git branch
  1. 切换分支到主分支上
git checkout master
  1. 在主分支上合并login分支的代码
git merge login
  1. 推送到码云中
git push
  1. 查看码云 (只有一个master分支)

https://gitee.com/ykang2020/vue_shop

  1. 将login分支也推送到码云中
git checkout login
git push -u origin login

4. 主页布局

4.1 整体布局

<el-container class="home_container">
  
  <el-header>Headerel-header>
  
  <el-container>
    
    <el-aside width="200px">Asideel-aside>
    
    <el-main>Mainel-main>
  el-container>
el-container>
.home_container {
     
  height: 100%;
}
.el-header {
     
  background-color: #373d41;
}
.el-aside {
     
  background-color: #333744;
}
.el-main {
     
  background-color: #eaedf1;
}

4.2 美化主页Header区域


<el-header>
  <div>
    <img src="../assets/heima.png" alt="" />
    <span>电商后台管理系统span>
  div>
  <el-button type="info" @click="logout">退出el-button>
el-header>
.el-header {
     
  background-color: #373d41;
  display: flex;
  justify-content: space-between;
  padding-left: 0;
  align-items: center;
  color: #fff;
  font-size: 20px;
}
.el-header > div {
     
  display: flex;
  align-items: center;
}
.el-header > div > span {
     
  margin-left: 15px;
}

4.3 实现左侧导航菜单的基本结构

菜单分为二级,并且可以折叠


<el-menu>
  <el-submenu>
    
    <i class="el-icon-menu">i>
    <span>一级菜单span>
    
    <el-menu-item>
  	  <i class="el-icon-menu">i>
  	  <span slot="title">二级菜单span>
  	el-menu-item>
  el-submenu>
el-menu>

4.4 通过axios拦截器添加token验证

需要授权的 API ,必须在请求头中使用 Authorization字段提供 token 令牌

后台除了登录接口之外,都需要token权限验证,我们可以通过添加axios请求拦截器来添加token,以保证拥有获取数据的权限
在main.js中添加代码,在将axios挂载到vue原型之前添加下面的代码

// 通过axios请求拦截器添加token,保证拥有获取数据的权限
axios.interceptors.request.use(config => {
     
  // 为请求头对象,添加 Token 验证的 Authorization 字段
  // console.log(config)
  config.headers.Authorization = window.sessionStorage.getItem('token')
  // 在最后必须 return config
  return config
})

4.5 获取左侧菜单数据

Home.vue
页面加载之前就要获取数据,定义生命周期函数

data() {
     
  return {
     
    // 左侧菜单数据
    menulist: []
  }
},
created() {
     
  this.getMenuList()
  this.activePath = window.sessionStorage.getItem('activePath')
},
methods: {
     
  // 获取所有的菜单
  async getMenuList() {
     
    const {
      data: result } = await this.$http.get('menus')
    if (result.meta.status !== 200) return this.$message.error(result.meta.msg)
    this.menulist = result.data
    console.log(result)
  }
}

4.6 通过双层for循环渲染左侧菜单


  <el-submenu :index="item.id+''" v-for="item in menulist" :key="item.id">
    
    <template slot="title">
      
      <span>{
    {item.authName}}span>
  template>
  
  <el-menu-item :index="subItem.id+''" v-for="subItem in item.children" :key="subItem.id">
    
    <i class="el-icon-menu">i>
    
    <span>{
    {subItem.authName}}span>
  el-menu-item>
el-submenu>

4.7 为选中项设置字体颜色并添加分类图标

通过更改el-menu的active-text-color属性可以设置侧边栏菜单中点击的激活项的文字颜色

<el-menu background-color="#333744" text-color="#fff" active-text-color="rgb(64,158,255)">

通过更改菜单项模板(template)中的i标签的类名,可以将左侧菜单栏的图标进行设置

在数据中添加一个iconsObj,然后将图标类名进行数据绑定

iconsObj: {
     
  125: 'el-icon-s-custom',
  103: 'el-icon-s-check',
  101: 'el-icon-s-goods',
  102: 'el-icon-s-order',
  145: 'el-icon-s-marketing'
}

一级菜单图标绑定iconsObj中的数据:

<!-- 图标 -->
<i :class="iconsObj[item.id]"></i>

4.8 每次只能打开一个菜单项并解决边框问题

为了保持左侧菜单每次只能打开一个,显示其中的子菜单,我们可以在el-menu中添加一个属性unique-opened
或者也可以数据绑定进行设置(此时true认为是一个bool值,而不是字符串) :unique-opened=“true”

<el-menu unique-opened>

解决边框问题

.el-menu {
     
  border-right: none;
}

4.9 实现侧边栏的折叠与展开效果


<el-aside :width="isCollapse ? '64px':'200px'">
  <div class="toggle-button" @click="toggleCollapse">|||div>
  
  <el-menu :collapse="isCollapse" :collapse-transition="false">
.toggle-button {
     
  background-color: #4A5064;
  font-size: 10px;
  line-height: 24px;
  color: rgb(144,147,153);
  text-align: center;
  letter-spacing: 0.2em;
  cursor: pointer
}
// 点击按钮切换菜单折叠与展开
toggleCollapse() {
     
  this.isCollapse = !this.isCollapse
}

4.10 实现首页路由的重定向效果

  1. 新增子级路由组件components/Welcome.vue
  2. 在router/index.js中导入子级路由组件,并设置路由规则以及子级路由的默认重定向
import Welcome from '../components/Welcome.vue'
const routes = [
  {
     
    path: '/home',
    component: Home,
    redirect: '/welcome',
    children: [{
      path: '/welcome', component: Welcome }]
  }
]
  1. 打开Home.vue,在main的主体结构中添加一个路由占位符

<el-main>
  
  <router-view>router-view>
el-main>

4.11 实现侧边栏路由链接的改造

  1. 需要将所有的侧边栏二级菜单都改造成子级路由链接,我们只需要将el-menu的router属性设置为true就可以了,此时当我们点击二级菜单的时候,就会根据菜单的index属性进行路由跳转,如: /110,
<el-menu router>
  1. 使用index id来作为跳转的路径不合适,我们可以重新绑定index的值为:index="’/’+subItem.path"

<el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id">

4.12 Home完整代码

<template>
  <el-container class="home_container">
    
    <el-header>
      <div>
        <img src="../assets/heima.png" alt="" />
        <span>电商后台管理系统span>
      div>
      <el-button type="info" @click="logout">退出el-button>
    el-header>
    
    <el-container>
      
      <el-aside :width="isCollapse ? '64px':'200px'">
        <div class="toggle-button" @click="toggleCollapse">|||div>
        
        <el-menu
          background-color="#333744"
          text-color="#fff"
          active-text-color="rgb(64,158,255)"
          unique-opened
          :collapse="isCollapse"
          :collapse-transition="false"
          router
          :default-active="activePath"
        >
        
          <el-submenu :index="item.id+''" v-for="item in menulist" :key="item.id">
            
            <template slot="title">
              
              <i :class="iconsObj[item.id]">i>
              
              <span>{
    {item.authName}}span>
            template>
            
            <el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id" @click="saveNavState('/'+subItem.path)">
              
              <i class="el-icon-menu">i>
              
              <span>{
    {subItem.authName}}span>
            el-menu-item>
          el-submenu>
        el-menu>
      el-aside>
      
      <el-main>
        
        <router-view>router-view>
      el-main>
    el-container>
  el-container>
template>

<script>
export default {
      
  data() {
      
    return {
      
      // 左侧菜单数据
      menulist: [],
      // 定义一个字体图标对象
      iconsObj: {
      
        125: 'el-icon-s-custom',
        103: 'el-icon-s-check',
        101: 'el-icon-s-goods',
        102: 'el-icon-s-order',
        145: 'el-icon-s-marketing'
      },
      isCollapse: false,
      // 被激活的链接地址
      activePath: ''
    }
  },
  created() {
      
    this.getMenuList()
    this.activePath = window.sessionStorage.getItem('activePath')
  },
  methods: {
      
    logout() {
      
      window.sessionStorage.clear()
      this.$router.push('/login')
      this.$message.warning('已退出')
    },
    // 获取所有的菜单
    async getMenuList() {
      
      const {
       data: result } = await this.$http.get('menus')
      if (result.meta.status !== 200) return this.$message.error(result.meta.msg)
      this.menulist = result.data
      console.log(result)
    },
    // 点击按钮切换菜单折叠与展开
    toggleCollapse() {
      
      this.isCollapse = !this.isCollapse
    },
    // 保存链接的激活状态
    saveNavState(activePath) {
      
      window.sessionStorage.setItem('activePath', activePath)
      this.activePath = activePath
    }
  }
}
script>

<style scoped>
.home_container {
      
  height: 100%;
}
.el-header {
      
  background-color: #373d41;
  display: flex;
  justify-content: space-between;
  padding-left: 0;
  align-items: center;
  color: #fff;
  font-size: 20px;
}
.el-header > div {
      
  display: flex;
  align-items: center;
}
.el-header > div > span {
      
  margin-left: 15px;
}
.el-aside {
      
  background-color: #333744;
}
.toggle-button {
      
  background-color: #4A5064;
  font-size: 10px;
  line-height: 24px;
  color: rgb(144,147,153);
  text-align: center;
  letter-spacing: 0.2em;
  cursor: pointer
}
.el-menu {
      
  border-right: none;
}

.el-main {
      
  background-color: #eaedf1;
}

style>

5. 展示

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_第15张图片
项目地址https://gitee.com/ykang2020/vue_shop

你可能感兴趣的:(前端框架Vue,vue,javascript,html)