2022-07-05 vue项目-通用后台管理系统(四) 设置home页侧边栏的icon细节优化:动态绑定图标,自动关闭其他二级菜单,点击折叠和展开侧边栏

本文详细介绍了在Vue后台管理系统中如何动态绑定侧边栏图标,解决图标显示问题,调整icon与文字间距,并实现点击关闭其他二级菜单及折叠展开侧边栏功能。通过在data中声明对象绑定图标,利用unique-opened属性实现菜单互斥,同时优化菜单样式,提供完整的home.vue代码示例。


element的icon: https://element.eleme.cn/#/zh-CN/component/icon

0.需求
  • 现在每个icon都是一样的,
  • 然后图标与文字之间的间距是不合理的,需要进行美化:

因为是写死的:<i class="el-icon-location"></i>考虑做成动态绑定相应的图标系统
(如果引入和上述代码还是没有显示出图标,则需要看看在public/index.js中有没有引入在线css和js文件)
在这里插入图片描述

  • 最后再加上一个"只允许最多打开一个二级菜单"的功能
  • 以及实现一个点击后折叠&展开的功能
1.动态绑定相应的图标

原先是写死的:
<i class="el-icon-location"></i>
我们在data声明一个键值对对象(索引:icon名称)

iconObj: {
  1: "iconfont icon-user",
  2: "iconfont icon-gengduo",
  3: "iconfont icon-shouye",
  4: "iconfont icon-yanzhengma1",
  5: "iconfont icon-shoucang",
  6: "iconfont icon-fenxiang1",
}

这样,之前使用v-for动态绑定一级菜单和二级菜单的文字的同时,把icon图标也做成动态绑定的,即:写成这样的形式: <i :class="iconObj[item.id]"></i>
同理,二级菜单的icon也照此处理,唯一的区别是:一级菜单使用的是id,二级菜单使用的是菜单文字

  • 在data创建对象iconObj2,将菜单文字和element-ui 的icon绑定
iconObj2:{
'用户管理':'iconfont icon-Management',
'员工管理':'iconfont icon-quanxianguanli',
'商品管理':'iconfont icon-shangpinguanli',
'订单管理':'iconfont icon-dingdanguanli',
'数据统计':'iconfont icon-shujutongji',
'用户列表':'iconfont icon-yonghuliebiao',
'员工列表':'iconfont icon-role-list',
'权限列表':'iconfont icon-permissions-list',
'商品列表':'iconfont icon-shangpinliebiao',
'分类参数':'iconfont icon-quanbu',
'商品分类':'iconfont icon-fenleigongnengleimu',
}
  • 把二级菜单中引入icon的标签改成动态绑定
<!-- 一级菜单下的二级菜单 -->
<!-- <el-menu-item index="1-4"> 改成动态绑定: -->
  <el-menu-item :index="subitem.path" v-for="subitem in item.child" :key="subitem.id">
  <!-- 二级菜单的模板 -->
  <template slot="title">
    <!-- 二级菜单图标 -->
    <!-- <i class="el-icon-fenleigongnengleimu"></i> -->
    <i :class="iconObj2[subitem.name]"></i>
    <!-- 二级菜单文本 -->
    <!-- <span>二级菜单</span> -->
    <span>{{subitem.name}}</span>
  </template>
</el-menu-item>
2.遇到的小bug:图标显示不出来

原因:前后引入了不一样的在线css 图标,当时注释了一个,但其实另一个才是代码需要的,
即:你用el-icon-shoucang这样的图标名,它能给你识别出来

<!-- <link rel="stylesheet" href="//at.alicdn.com/t/c/font_3869922_ok78ubh3b5o.css"> -->
<link rel="stylesheet" href="//at.alicdn.com/t/font_2423689_rabjgtavn39.css">
3.微调一下icon和字体的间距

现在是这样的:
在这里插入图片描述
设置iconfont的右外边距:

.iconfont {
  margin-right: 40px;
}

效果:略

4.实现功能:点开一个其他自动关闭

使用到了unique-opened这个属性:https://element.eleme.cn/#/zh-CN/component/menu#navmenu-dao-hang-cai-dan
在这里插入图片描述
添加在el-menu标签中: <el-menu :unique-opened="true">

5.其他小调整
  • Aside和Main之间的背景的交接处多了1px的空间 ,需要用css调整下
.el-menu {
  border-right: none;
}
  • 把左侧菜单栏改成和登录框一样的背景色
<!-- 左侧菜单区域 -->
<!-- <el-menu default="2" class="el-menu-vertival-deme"> -->
<el-menu 
  default-active="2"
  class="el-menu-vartical-demo"
  :unique-opened="true"
  background-color="#121a2a"
  text-color="#fff"
>

样式:

/* Aisde侧边栏的样式*/
.el-aside {
  background: #d3dce6;
  line-height: 400px;
}
  • 二级菜单没有明显的缩进,所以我自己设置了左侧的内边距来作为缩进
.el-menu-item{
  padding-left:60px !important;
}

设置前:
在这里插入图片描述
设置后:
在这里插入图片描述
猜测可能是从element-ui官网上引入的时候有些格式上的小问题,但是这是无关紧要的小问题,故此略过
(缺点:点击折叠的时候显示不全)

6.新增一个点击折叠展开功能
参考了:折叠与收起功能
  • 这个折叠与展开写在Aside最上面:
<!-- <el-aside width="200px">改成动态宽度: -->
<el-aside class="elaside" :width="isopen ? '200px' : '50px'">
  <!-- 折叠与展开功能 -->
  <div class="togglebtn" @click="switchMenu">
      <i :class="isopen?'el-icon-s-fold':'el-icon-s-unfold'"></i>
  </div>
  • 给一个样式:
.togglebtn{
  color:#fff;
  text-align: left;
  line-height: 24px;
  font-size:16px;
  padding-left:10px;
  background: darkcyan;
  cursor:pointer;
}
.elaside{
  transition:all .3s ease;
}
  • 核心逻辑:点击就改变isopen的布尔值
data() {
    return {
      isopen: true,
      ...
    };
  },
methods: {
	...
    switchMenu(){
      this.isopen=!this.isopen;
    },
},
效果
  • el-icon-s-fold和el-icon-s-unfold分别长这样:
    在这里插入图片描述
  • 折叠前:
    在这里插入图片描述
  • 折叠后:
    在这里插入图片描述
7.完整代码:home.vue
<template>
  <div class="home">
    <!-- 引入elementui布局容器:el-container -->
    <el-container>
      <!-- 1.头部 -->
      <el-header>
        <div>
          <img src="https://s3.bmp.ovh/imgs/2023/01/27/d44acfed1a1f8b1b.jpg" />
          <span class="title">Gaara网络科技有限公司后台管理系统</span>
        </div>
        <el-button type="success" @click="logOut" size="mini"
          >退出登录</el-button
        >
      </el-header>
      <!-- 2.侧边栏和主体内容 -->
      <el-container>
        <!-- 2.1.侧边栏 -->
        <!-- <el-aside width="200px">改成动态宽度: -->
        <el-aside class="elaside" :width="isopen ? '200px' : '50px'">
          <!-- 折叠与展开功能 -->
          <div class="togglebtn" @click="switchMenu">
              <i :class="isopen?'el-icon-s-fold':'el-icon-s-unfold'"></i>
          </div>
          <!-- 使用el-menu进行aside侧边栏布局 -->
          <!-- 左侧菜单区域 -->
          <!-- <el-menu default="2" class="el-menu-vertival-deme"> -->
          <el-menu 
            default-active="2"
            class="el-menu-vartical-demo"
            :unique-opened="true"
            background-color="#121a2a"
            text-color="#fff"
            :router="true"
          >
            <!-- 一级菜单 -->
            <!-- <el-submenu index="1"> 改成动态绑定: -->
              <el-submenu :index="item.id+''" v-for="item in menulist" :key="item.id">
              <!-- 一级菜单的模板 -->
              <template slot="title">
                <!-- 菜单图标 -->
                <!-- <i class="el-icon-location"></i> -->
                <i :class="iconObj[item.id]"></i>
                <!-- 文本 -->
                <!-- <span>导航1</span> -->
                <span>{{item.name}}</span>
              </template>
              <!-- 一级菜单下的二级菜单 -->
              <!-- <el-menu-item index="1-4"> 改成动态绑定: -->
                <el-menu-item :index="subitem.path" v-for="subitem in item.child" :key="subitem.id">
                <!-- 二级菜单的模板 -->
                <template slot="title">
                  <!-- 二级菜单图标 -->
                  <!-- <i class="el-icon-fenleigongnengleimu"></i> -->
                  <i :class="iconObj2[subitem.name]"></i>
                  <!-- 二级菜单文本 -->
                  <!-- <span>二级菜单</span> -->
                  <span>{{subitem.name}}</span>
                </template>
              </el-menu-item>
            </el-submenu>
          </el-menu>
        </el-aside>
        <!-- 2.2.主体内容 -->
        <el-main>Main</el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
export default {
  name: "Home",
  components: {},
  props: [],
  data() {
    return {
      menulist:[],
      isopen: true,
      iconObj: {
        1: "iconfont icon-user",
        2: "iconfont icon-gengduo",
        3: "iconfont icon-shouye",
        4: "iconfont icon-yanzhengma1",
        5: "iconfont icon-shoucang",
        6: "iconfont icon-fenxiang1",
      },
        iconObj2:{
        '用户管理':'iconfont icon-Management',
        '员工管理':'iconfont icon-quanxianguanli',
        '商品管理':'iconfont icon-shangpinguanli',
        '订单管理':'iconfont icon-dingdanguanli',
        '数据统计':'iconfont icon-shujutongji',
        '用户列表':'iconfont icon-yonghuliebiao',
        '员工列表':'iconfont icon-role-list',
        '权限列表':'iconfont icon-permissions-list',
        '商品列表':'iconfont icon-shangpinliebiao',
        '分类参数':'iconfont icon-quanbu',
        '商品分类':'iconfont icon-fenleigongnengleimu',
      }
    };
  },
  watch: {},
  computed: {},
  methods: {
    logOut() {
      // 清空数据
      window.sessionStorage.clear();
      // 点击退出登录后自动跳转到登录页
      this.$router.push("/Login");
    },
    async getmenus() {
      // 这里对标的是vue.config.js中的"./api/menu"
      const res = await this.$http.get("/api/menu");
      console.log(res.data);
      if (!res.status == "ok") return;
      this.menulist = res.data.data;
    },
    switchMenu(){
      this.isopen=!this.isopen;
    },
  },
  created() {
    this.getmenus();
  },
  mounted() {},
};
</script>
<style lang="scss" scoped>
/*home主页的样式 */
.el-container {
  height: 100vh;
}
/*头部header的样式*/
.el-header {
  display: flex;
  /* el-header下的子元素会显示在两边 */
  justify-content: space-between;
  align-items: center;
  background: #0c212b;
  height: 80px !important;
}
.el-header > div {
  display: flex;
  align-items: center;
}
.el-header img {
  width: 60px;
  height: 60px;
  padding-right: 16px;
}
.el-header .title {
  color: #fff;
  font-size: 30px;
}
/* Aisde侧边栏的样式*/
.el-aside {
  background: #d3dce6;
  line-height: 400px;
}
.togglebtn{
  color:#fff;
  text-align: left;
  line-height: 24px;
  font-size:16px;
  padding-left:10px;
  background: darkcyan;
  cursor:pointer;
}
.elaside{
  transition:all .3s ease;
}
.iconfont {
  margin-right: 40px;
}
.el-menu {
  border-right: none;
}
.el-menu-item{
  padding-left:60px !important;
}
/*Main主体样式*/
.el-main {
  background: #e9eef3;
  line-height: 400px;
}
</style>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值