实现主页布局

获取左侧菜单列表

<template>
    <el-container>
        <!-- 头部 -->
  <el-header>
      <div class="left">
          <img src="../assets/imgs/shop.png" alt="">
          <span>后台管理系统</span>
      </div>
      <div class="right">
          <span>欢迎您:{{userInfo.username}}</span>
          <el-button type="danger" size="mini" @click="logout">退出</el-button>
      </div>
  </el-header>
  <el-container>
      <!-- 侧边栏 -->
    <el-aside width="200px">
        <!--侧边菜单-->
        <el-menu
      default-active="2"
      class="el-menu-vertical-demo"
     >
      <el-submenu index="1">
        <template slot="title">
          <i class="el-icon-location"></i>
          <span>导航一</span>
        </template>
          <el-menu-item index="1-4-1">选项1</el-menu-item>
          <el-menu-item index="1-4-1">选项2</el-menu-item>
          <el-menu-item index="1-4-1">选项3</el-menu-item>
      </el-submenu>
    </el-menu>
    </el-aside>
    <!-- 主题区域 -->
    <el-main>Main</el-main>
  </el-container>
</el-container>
</template>

<script>
export default {
    data(){
        return{
            userInfo:null,
            menuList:[]
        }
    },

    created(){
        // 获取用户信息  用以展示到首页
        this.userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
        this.getMenuList()
    },
    methods:{
        // 退出
        logout(){
            this.$confirm('确定要退出登录吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
            // 点击确定后  清除session用户信息
          sessionStorage.clear()
          // 跳转到登录页面
          this.$router.push('/login')
        }).catch(() => {
        //   this.$message({
        //     type: 'info',
        //     message: '已取消退出'
        //   });          
        });
        },
        // 获取左侧的菜单列表
        // 使用async await 修饰
        async getMenuList(){
            const {data:res} = await this.$http.get('menus')
            if(res.meta.status !==200){
                return this.$message.error(res.meta.msg)
            }
            this.menuList=res.data
        }
    }
    
}
</script>

<style lang='less' scope>
    .el-container{
        height: 100%;
    }
    .el-header{
        background: url('../assets/imgs/header_bg.gif') repeat-x center;  
        height: 50px!important;
        display: flex;
        justify-content: space-between;
        align-items: center;
        color: white;
        .left{
            display: flex;  //显示在同一行
            align-items: center; // 垂直对齐
            img{
                width: 40px;
                margin-right: 20px; // 图片和文字的距离
            }
            span{
                font-size: 20px;
            }
        }
        .right{
            margin-left: 10px;

        }
    }
</style>

会提示无效的token,因为除了登录页面其他请求都需要携带token,否则会认为是没有权限
实现主页布局_第1张图片
实现主页布局_第2张图片

在main.js中为请求头添加token

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'

// 导入全局样式表
import './assets/imgs/css/global.css'
//导入字体图标
import './assets/fonts/iconfont.css'
// 引入axios
import axios from 'axios'
Vue.prototype.$http = axios
    // 配置axios基础路径
axios.defaults.baseURL = 'http://www.tangxiaoyang.vip:8888/api/v2'
    // 拦截所有请求,为请求头添加token认证(拦截器)
axios.interceptors.request.use(config => {
    // 获取用户信息
    const userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
        // 向请求头中添加token
    config.headers.Authorization = userInfo ? userInfo.token : ''
    return config

})


Vue.config.productionTip = false

new Vue({
    router,
    render: h => h(App)
}).$mount('#app')

在退出再登录的时候会报错显示获取不到token,因为登录的时候就会验证token,那时候还没把token添加到session中所以获取不到,这里做个判断

config.headers.Authorization = userInfo ? userInfo.token : ''

menuList 数据结构
实现主页布局_第3张图片

       <!--侧边菜单-->
        <el-menu
      default-active="2"
      class="el-menu-vertical-demo"
     >
      <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">
              <i class="el-icon-menu"></i>
              {{subItem.authName}}
          </el-menu-item>
          
      </el-submenu>
    </el-menu>

实现主页布局_第4张图片

每个一级菜单前面的图标都是一样的,但是实际上应该是不一样的

data(){
        return{
            //用户信息
            userInfo:null,
            // 左侧菜单列表
            menuList:[],
            // 图标样式对象
            iconObj:{
                '201':'iconfont icon-shouye',
                '125':'iconfont icon-users',
                '103':'iconfont icon-tijikongjian',
                '101':'iconfont icon-shangpin',
                '102':'iconfont icon-danju',
                
            }

        }
    },
 <!--侧边菜单-->
        <el-menu
      default-active="2"
      class="el-menu-vertical-demo"
     >
      <el-submenu :index="item.id+''" v-for="item in menuList" :key='item.id'>
        <template slot="title">
          <i :class="iconObj[item.id]"></i>
          <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>
              {{subItem.authName}}
          </el-menu-item>
          
      </el-submenu>
    </el-menu>

实现主页布局_第5张图片

左侧导航栏优化
默认同时可打开多个菜单,限制设置为同一时间只能打开一个
实现主页布局_第6张图片
unique-opened

 <el-menu
      default-active="2"
      unique-opened
     >
      <el-submenu :index="item.id+''" v-for="item in menuList" :key='item.id'>
        <template slot="title">
          <i :class="iconObj[item.id]"></i>
          <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>
              {{subItem.authName}}
          </el-menu-item>
          
      </el-submenu>
    </el-menu>

添加router属性 就有了路由跳转的功能
是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转
实现主页布局_第7张图片

登录后跳转到首页home,现在需要点击首页中的欢迎页,把内容展示到home主体部分
实现主页布局_第8张图片

在这里插入图片描述
index.js中配置路由
在home下的children中配置,这里是把欢迎页的内容展示在home页主体部分,所以需要在

const routes = [
    // 访问根路径的时候跳转到login
    {
        path: '/',
        redirect: '/login'
    },
    {
        path: '/login',
        component: Login
    },
    {
        path: '/home',
        component: () =>
            import ('../components/Home.vue'),
        children: [{
            path: '/welcome',
            component: () =>
                import ('../components/index/Welcome.vue')
        }]
    }
]

home.vue

<!-- 主题区域 -->
    <el-main>
        <router-view></router-view>
    </el-main>

这里默认是登录后跳转到home页,这里可以重定向到欢迎页

index.js

{
        path: '/home',
        component: () =>
            import ('../components/Home.vue'),
        redirect: '/welcome',
        children: [{
            path: '/welcome',
            component: () =>
                import ('../components/index/Welcome.vue')
        }]
    }

设置默认选择欢迎页,高亮

    <!--侧边菜单-->
        <el-menu
      :default-active="$route.path"
      unique-opened
      router
     >
     
      <el-submenu :index="item.id+''" v-for="item in menuList" :key='item.id'>
        <template slot="title">
          <i :class="iconObj[item.id]"></i>
          <span>{{item.authName}}</span>
        </template>
            <!--这里的index是要跳转的地址 -->
          <el-menu-item :index="'/'+ subItem.path" v-for="subItem in item.children" :key="subItem.id">
              <i class="el-icon-menu"></i>
              {{subItem.authName}}
          </el-menu-item>
      </el-submenu>
    </el-menu>

折叠左侧菜单

  <!-- 侧边栏 -->
      <!-- 这个宽度设置成动态的 没折叠是200,折叠的话设置小一点 -->
    <el-aside :width="isCollapse ? '64px' : '200px' ">
        <!--菜单的折叠和显示-->
        <!-- isCollapse 菜单是否折叠  -->
        <div class="toggle-button" @click="isCollapse=!isCollapse">|||</div>
        <!--侧边菜单-->
        <el-menu
      :default-active="$route.path"
      unique-opened
      router
      :collapse='isCollapse'
      :collapse-transition="false"
     >
      <el-submenu :index="item.id+''" v-for="item in menuList" :key='item.id'>
        <template slot="title">
          <i :class="iconObj[item.id]"></i>
          <span>{{item.authName}}</span>
        </template>
            <!--这里的index是要跳转的地址 -->
          <el-menu-item :index="'/'+ subItem.path" v-for="subItem in item.children" :key="subItem.id">
              <i class="el-icon-menu"></i>
              {{subItem.authName}}
          </el-menu-item>
      </el-submenu>
    </el-menu>
    </el-aside>
 data(){
        return{
            //用户信息
            userInfo:null,
            // 左侧菜单列表
            menuList:[],
            // 图标样式对象
            iconObj:{
                '201':'iconfont icon-shouye',
                '125':'iconfont icon-users',
                '103':'iconfont icon-tijikongjian',
                '101':'iconfont icon-shangpin',
                '102':'iconfont icon-danju',
                
            },
            // 是否折叠左侧菜单
            isCollapse:false

        }
    },

完整代码

<template>
    <el-container>
        <!-- 头部 -->
  <el-header>
      <div class="left">
          <img src="../assets/imgs/shop.png" alt="">
          <span>后台管理系统</span>
      </div>
      <div class="right">
          <span>欢迎您:{{userInfo.username}}</span>
          <el-button type="danger" size="mini" @click="logout">退出</el-button>
      </div>
  </el-header>
  <el-container>
      <!-- 侧边栏 -->
      <!-- 这个宽度设置成动态的 没折叠是200,折叠的话设置小一点 -->
    <el-aside :width="isCollapse ? '64px' : '200px' ">
        <!--菜单的折叠和显示-->
        <!-- isCollapse 菜单是否折叠  -->
        <div class="toggle-button" @click="isCollapse=!isCollapse">|||</div>
        <!--侧边菜单-->
        <el-menu
      :default-active="$route.path"
      unique-opened
      router
      :collapse='isCollapse'
      :collapse-transition="false"
     >
      <el-submenu :index="item.id+''" v-for="item in menuList" :key='item.id'>
        <template slot="title">
          <i :class="iconObj[item.id]"></i>
          <span>{{item.authName}}</span>
        </template>
            <!--这里的index是要跳转的地址 -->
          <el-menu-item :index="'/'+ subItem.path" v-for="subItem in item.children" :key="subItem.id">
              <i class="el-icon-menu"></i>
              {{subItem.authName}}
          </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{
            //用户信息
            userInfo:null,
            // 左侧菜单列表
            menuList:[],
            // 图标样式对象
            iconObj:{
                '201':'iconfont icon-shouye',
                '125':'iconfont icon-users',
                '103':'iconfont icon-tijikongjian',
                '101':'iconfont icon-shangpin',
                '102':'iconfont icon-danju',
                
            },
            // 是否折叠左侧菜单
            isCollapse:false

        }
    },

    created(){
        // 获取用户信息  用以展示到首页
        this.userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
        this.getMenuList()
    },
    methods:{
        // 退出
        logout(){
            this.$confirm('确定要退出登录吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
            // 点击确定后  清除session用户信息
          sessionStorage.clear()
          // 跳转到登录页面
          this.$router.push('/login')
        }).catch(() => {
        //   this.$message({
        //     type: 'info',
        //     message: '已取消退出'
        //   });          
        });
        },
        // 获取左侧的菜单列表
        // 使用async await 修饰
        async getMenuList(){
            const {data:res} = await this.$http.get('menus')
            if(res.meta.status !==200){
                return this.$message.error(res.meta.msg)
            }
            this.menuList=res.data
            console.log(this.menuList)
        }
    }
    
}
</script>

<style lang='less' scope>
    .el-container{
        height: 100%;
    }
    .el-header{
        background: url('../assets/imgs/header_bg.gif') repeat-x center;  
        height: 50px!important;
        display: flex;
        justify-content: space-between;
        align-items: center;
        color: white;
        .left{
            display: flex;  //显示在同一行
            align-items: center; // 垂直对齐
            img{
                width: 40px;
                margin-right: 20px; // 图片和文字的距离
            }
            span{
                font-size: 20px;
            }
        }
        .right{
            margin-left: 10px;

        }
    }
    .el-aside{
        .el-menu{
            border-right: 0; //不需要有边框
            .iconfont{
                margin-right: 10px;
            }
        }
        .toggle-button{
            background: #60779d;
            font-size: 10px;
            line-height: 24px;
            text-align: center;
            color: white;
            letter-spacing: 0.2rem; //字符间距
            cursor: pointer; //鼠标移上去是手的样式
        }
    }
    .el-main{
        background: #eaedf1;
    }

</style>

你可能感兴趣的:(Vue,javascript,前端,css)