电商后台管理项目主页实现

1,222 阅读1分钟

一、页面布局

<template>
  <div class="home">
    <el-container class="home-conatiner">
      <!-- 头部区域 -->
      <el-header>
        <div>
          <img src="../assets/logo.png" alt="" />
          <span>电商后台管理系统</span>
        </div>
        <el-button type="info" @click="outlogin">退出登录</el-button>
      </el-header>
      <!-- 页面主体区域 -->
      <el-container>
        <!-- 侧边栏(左) -->
        <el-aside width="200px">
          <!-- 菜单区域 -->
          <el-menu
            background-color="#333744"
            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 index="1-4-1">
                <!-- 二级菜单模板区域 -->
                <template slot="title">
                  <i class="el-icon-location"></i>
                  <span>导航一</span>
                </template>
              </el-menu-item>
            </el-submenu>
          </el-menu>
        </el-aside>
        <!-- 右侧内容主体 -->
        <el-main>Main</el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script>
export default {
  data: () => ({}),
  methods: {
    // 退出登录
    outlogin() {
      // 清除token
      window.sessionStorage.clear()
      // 跳转到登录页面
      this.$router.push('/login')
    }
  }
}
</script>
<style lang="less" scoped>
.home {
  height: 100%;
  .home-conatiner {
    height: 100%;
    .el-header {
      background-color: #373d41;
      align-items: center;
      display: flex;
      justify-content: space-between;
      div {
        display: flex;
        justify-content: start;
        align-items: center;
        img {
          width: 60px;
          height: 60px;
          background-color: white;
          border-radius: 50%;
        }
        span {
          font-size: 20px;
          color: white;
          padding-left: 30px;
        }
      }
      .el-button {
      }
    }
    .el-aside {
      background-color: #333744;
    }
    .el-main {
      background-color: #eaedf1;
    }
  }
}
</style>

image.png

二、通过axios拦截器添加token验证

  • 因为后续的每一项操作都需要token权限,所以在请求数据前先为请求头添加token,再返回请求 image.png
  • main.js中设置请求拦截

image.png

  • 此时请求头中还没有token

image.png

  • 添加Authorization属性值

image.png

三、获取左侧菜单数据

  • 1.在页面加载时就获取数据
created() {
    this.getMenuList()
  },
  • 2.定义函数获取数据
// 获取左侧所有菜单
    async getMenuList() {
      // 结构数据data,并取名为res
      const { data: res } = await this.$http.get('menus')
      console.log(res)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.menulist = res.data
      console.log(this.menulist)
    }
  }
  • 3.把获取到的数据放到data中定义的数组里
data: () => ({
    menulist: []
  }),

image.png

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

  • 外层循环用来渲染一级菜单,内层循环用来渲染二级菜单
  • 为了让鼠标点开任意一个一级菜单,不会影响到其他一级菜单,添加':index'属性,并且为解决报错,使index的值加上一个空字符,变成一个字符串
<!-- 一级菜单 -->
            <el-submenu
              :index="item.id + ''"
              v-for="item in menulist"
              :key="item.id"
            >
              <!-- 一级菜单模板区域 -->
              <template slot="title">
                <i class="el-icon-location"></i>
                <span>{{ item.authName }}</span>
              </template>
              <!-- 二级菜单 -->
              <el-menu-item
                :index="subitem.id + ''"
                v-for="subitem in item.children"
                :key="subitem.id"
              >
                <!-- 二级菜单模板区域 -->
                <template slot="title">
                  <i class="el-icon-location"></i>
                  <span>{{ subitem.authName }}</span>
                </template>
              </el-menu-item>
            </el-submenu>

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

  • 1.设置选中二级菜单的颜色

image.png

  • 2.设置二级菜单的图标

image.png

  • 3.设置以及菜单图标
    • 1.定义一个数组,里面存放每个一级菜单的id,并为其设置图标名称
    data: () => ({
        menulist: [],
        iconlist: {
          125: 'el-icon-user-solid',
          103: 'el-icon-present',
          101: 'el-icon-s-goods',
          102: 'el-icon-s-order',
          145: 'el-icon-monitor'
        }
      }),
    
    • 2.将inconlist数据渲染到页面
    <!-- 一级菜单模板区域 -->
    <template slot="title">
    <i :class="iconlist[item.id]"></i>
    <span>{{ item.authName }}</span>
    </template>
    

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

  • 1.给menu添加unique-opened属性
<el-menu
            background-color="#333744"
            text-color="#fff"
            active-text-color="#409EFF"
            unique-opened
          >
  • 2.边框问题(对不齐)

image.png

  • 解决:给el-meun添加border:none样式
     .el-menu {
     border: none;
   }

七、实现侧边栏菜单的折叠展开效果

  • 1.在侧边栏顶部添加一个div盒子,默认展开菜单,点击后折叠菜单
<div class="toggle-button" @click="toggle">|||</div>
  • 2.collapse是否水平折叠收起菜单(仅在 mode 为 vertical 时可用),collapse-transition是否开启折叠动画,给menu添加collapse属性和collapse-transition属性
<el-menu
   background-color="#333744"
   text-color="#fff"
   active-text-color="#409EFF"
   unique-opened
   :collapse="isCollapse"
   :collapse-transition="false"
>
         
         
   data: () => ({
   menulist: [],
   iconlist: {
     125: 'el-icon-user-solid',
     103: 'el-icon-present',
     101: 'el-icon-s-goods',
     102: 'el-icon-s-order',
     145: 'el-icon-monitor'
   },
   isCollapse: false
 }),
// 点击按钮 切换菜单 折叠展开
   toggle() {
     this.isCollapse = !this.isCollapse
   }
  • 3.让侧边栏的宽度随着展开和折叠而变化
<el-aside :width="isCollapse ? '64px' : '200px'">

八、实现首页路由的重定向

  • 1.创建Welcome.vue组件
<template>
 <div>Welcome</div>
</template>
<script>
export default {
 data: () => ({})
}
</script>
<style lang="less" scoped>
</style>

  • 2.配置路由(在home路由中定义子路由)
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import Home from '../components/Home.vue'
import Welcome from '../components/Welcome.vue'

Vue.use(VueRouter)

const routes = [
 // 重定向
 {
   path: '/',
   redirect: '/login'
 },
 {
   path: '/login',
   component: Login
 },
 {
   path: '/home',
   component: Home,
   redirect: '/welcome',
   children: [
     {
       path: '/welcome',
       component: Welcome
     }
   ]
 }
]

const router = new VueRouter({
 routes
})

// to 将要访问的路径
// from 代表从哪个路径跳转而来
// next 是一个函数 表示放行
// next() 放行   next('/login')  强制跳转
router.beforeEach((to, from, next) => {
 // 如果将要访问的路径是login,就放行
 if (to.path === '/login') return next()
 // 获取token
 const token = window.sessionStorage.getItem('token')
 // 如果token不存在,则强制跳转到登录页面
 if (!token) return next('/login')
 // 如果token存在,则放行
 next()
})

export default router

  • 3.在Home.vue组件中添加路由占位符,将Welcome渲染到home页面
<!-- 右侧内容主体 -->
       <el-main>
         <!-- 路由占位符 -->
         <router-view></router-view>
       </el-main>

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

  • 1.为侧边栏开启路由模式(为menu添加router属性,或:router="true")
    <el-menu
           background-color="#333744"
           text-color="#fff"
           active-text-color="#409EFF"
           unique-opened
           :collapse="isCollapse"
           :collapse-transition="false"
           router
         >
  • 此时,点击二级菜单跳转,发现地址栏中的路径是二级菜单的id,这样不好

image.png

  • 2.修改地址
    <!-- 二级菜单 -->
              <el-menu-item
                :index="'/' + subitem.path"
                v-for="subitem in item.children"
                :key="subitem.id"
              >

image.png