zoukankan      html  css  js  c++  java
  • vue 自定义侧边栏 递归无限子级菜单

    有很多网站会涉及到导航栏,我自己在开发中用的是element导航组件,并且自定义事件,给大家分享一下。

    1.使用递归方法,无限循环子级菜单。

    2.使用组件封装,维护方便。

    3.使用index作为路由跳转。

    4.结合后台动态渲染。

    5.自定义样式,修改默认icon。

    6.根据后台返回数据,动态设置默认选中。

     

     

     1.封装组件。

      首先创建好vue之后,在a_module里创建一个存放组件的文件夹,因为a_module是存放公共资源以及静态文件的,当然也可以根据喜好来创建。

     

     

     

    2.调用组件

      在要使用到的页面中使用 import 引入封装好的组件,components初始化一下,在页面中使用。

     

     

     

     

     

     

    注意:这里需要注意的是,在引用的页面中一定要el-menu包裹起来,可以在el-menu标签里来配置侧边栏的各种状态。

    3.组件传值

      

     

     

     我是后台拿到的数据,当然也可以自定义数据,在引用组建的页面内创建,在子组件标签上边自定义事件,在子组件用props接收参数。

     

     

     4.el-menu配置

      这里呢,需要在父组件内配置侧边栏的各种状态,选中状态啦,index路由跳转啦,等等。

     

     

       这里呢,我主要配置了,router:开启index跳转路由,default-active:默认选中,这里呢我做了很多判断,大家可以根据实际情况来做处理,我主要是拿到当前地址,来做选中状态。active-text-color:配置字体颜色,等等

    5.子组件递归,无限循环子级

    我呢用的是递归的方法,他的原理呢就是自己调用自己。

      

     

     

     注意看红色框中的内容

    (1).大家可以看到,我在跟标签里边写了一个:class,主要原因就是,但你循环自己的时候,设置css样式只会生效一次,这个可以解决这个问题。

    (2).然后呢,根据数据结构,循环父组件传递过来的参数,如果没有children的话,循环下边的代码,不调用子级,如果有children的话证明有子级菜单,那么调用上边代码。

    (3).大家可以看到在label标签里我又调用了自己,然后传递参数,这里就是递归,如果满足条件就无线调用自己。

    (4).这里呢我用了自定义图标,大家可以观察我的布局。

    (5).到这里已经差不多了,但是要注意的是,:index,接受的是字符串形式的值,所以这里比较坑,需要的话可以用String()转化一下。

    (6).至于图片里getImgUrl()方法,是解决图片异步的一种方法。

     

     

     6.默认样式

    很多框架的默认样式是很难修改的,大家可以在页面中去找的class类名去修改,我用的是 /deep/ 这个是一个深度修饰符 或者是 >>> ,当然也可以在跟文件里去修改样式,但是我不建议这样去做,因为会他是全局修改,容易影响其他页面的样式。

     

    差不多就是这些了,样式的以及源码我在下边给大家附上。

    父组件:

    html:

    <el-menu
    :router="true"
    :default-active="(this.$route.meta[0].meta&&this.$route.meta[0].meta[0].path&&!this.$route.meta[0].meta[0].ispath)?this.$route.meta[0].meta[0].path:this.$route.meta[0].path"
    active-text-color="#ffffff"
    :unique-opened="true"
    background-color="#00bfb8"
    >
    <menutree :data="navigation" class="hr_one"></menutree>
    <!-- 侧边导航组件 -->
    </el-menu>
     
    css:
    .el-aside::-webkit-scrollbar {
     4px;
    background: #00d2ca;
    }
    .el-aside::-webkit-scrollbar-thumb {
    background: #009d97;
    border-top-right-radius: 10px;
    border-top-left-radius: 10px;
    border-bottom-right-radius: 10px;
    border-bottom-left-radius: 10px;
    }
    .el-main::-webkit-scrollbar {
    display: none;
    }
    .el-aside {
    text-align: center;
    position: absolute;
    top: 80px;
    bottom: 0;
    left: 0;
    background-color: #00bfb8 !important;
    min-height: 800px;
    .el-menu-item-group /deep/.el-menu-item-group__title {
    padding: 0 !important;
    }
    .el-menu-item:hover {
    background-color: #00d2ca;
    }
    .child_li {
    color: #ffff;
    display: flex;
    align-items: center;
    padding: 0;
    span:first-child {
    margin-left: 23px;
    }
    span:last-child {
    margin-left: 23px;
    }
    }
    }
    
    
    
     
    josn:
    这个数据呢,是我自己模拟的数据
    navigation: [
    {
     id:0,
     name: "首页",
     path: "/Hr-index/home",
    icon: "icon_hrIndex.png"
     },
     {
     id:1,
     name: "教职工档案",
    path: "/Hr-index/staffFiles",
    icon: "icon_staffFiles.png"
    },
     {
     id:2,
     name: "招聘信息",
     path: "",
     icon: "icon_hrJion.png",
     children: [
     { id: 122, name: "招聘申请", path: "/Hr-index/zpApply" },
     { id: 123, name: "招聘审核", path: "/Hr-index/zpCheck" },
     { id: 124, name: "结果统计", path: "/Hr-index/resultInfo" }
     ]
     },
     {
     id: 10,
     name: "解聘信息",
     path: "",
     icon: "icon_hrunBind.png",
     children: [
     { id: 119, name: "解聘信息", path: "/Hr-index/decruitment" },
     { id: 121, name: "解聘教师端", path: "/Hr-index/jpteacher" }
     ]
     },
     {
     id: 3,
     name: "劳资管理",
     path: "",
     icon: "icon_hrLabour.png",
     children: [
     { id: 117, name: "劳资详情", path: "/Hr-index/labour/details" },
     {
     id: 118,
     name: "岗位劳资设定",
     path: "/Hr-index/labour/setting"
     }
     ]
     },
     {
     id: 4,
     name: "考勤管理",
     path: "/Hr-index/check/manage",
     icon: "icon_manage.png"
     },
     {
     id: "5",
     name: "培训管理",
     path: "/Hr-index/modlifyift",
     icon: "icon_modifyift.png"
     },
     {
     id: "6",
     name: "离岗创业管理",
     path: "/Hr-index/Quit",
     icon: "icon_dimission.png"
     },
     {
     id: "7",
     name: "护照管理",
     icon: "icon_Passport.png",
     path: "/Hr-index/Passport"
     },
     {
     id: "8",
     name: "权限管理",
     icon: "icon_jurisdiction_li.png",
     path: "",
     children: [
     { id: "115", name: "人员管理", path: "/Hr-index/Jurisdiction_set" },
     { id: "116", name: "角色管理", path: "/Hr-index/Jurisdiction_role" }
     ]
     },
     {
     id: "11",
     name: "院系专业管理",
     path: "/Hr-index/yxhome",
     icon: "icon_yxhome.png"
     },
     {
     id: "",
     name: "课程管理",
     path: "/Hr-index/KcAdministration",
     icon: "icon_KcAdministration.png"
     },
     {
     id: "9",
     name: "个人信息",
     icon: "icon_Personal_li.png",
     path: "",
     children: [
     {
     id: "111",
     name: "个人档案rerwerwerwerwerwerwerwerwerwerwerwerwerwerwerwer",
     path: "/Hr-index/Personal_file"
     },
     { id: "112", name: "个人考勤", path: "/Hr-index/Personal_check" },
     { id: "113", name: "劳资详情", path: "/Hr-index/Personal_labour" },
     { id: "114", name: "培训详情", path: "/Hr-index/Personal_train" }
     ]
     }
    ], //导航数组
      

    子组件:

     

    html:

    <div class="menutree" :class="[calssName]">
    <div class>
    <label v-for="menu in data" :key="menu.index">
    <el-submenu :index="String(menu.id)" v-if="menu.children!=''">
    <!-- <el-submenu :index="String(menu.id)" v-if="menu.children"> -->
    <template slot="title">
    <img :src="getImgUrl(menu.icon)" alt v-if="menu.icon" />
    <span>{{menu.name}}</span>
    </template>
    <label>
    <menutree :data="menu.children" :calssName="calssName"></menutree>
    </label>
    </el-submenu>
    <el-menu-item :index="menu.path" v-else>
    <img :src="getImgUrl(menu.icon)" alt v-if="menu.icon" />
    <span
    style="display:block;4px;height:4px;background:#ffffff;margin-top:28px;margin-left:30px; border-radius:100%;"
    :style="{backgroundColor:calssName=='listtxt'?'#a6160a':'#ffffff',}"
    v-else
    ></span>
    <span
    slot="title"
    style="display:block;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;white-space : nowrap;"
    >{{menu.name}}</span>
    </el-menu-item>
    </label>
    </div>
    </div>
     
     
    script:
     
    import menutree from "./boss";
    export default {
    name: "menutree",
    data() {
    return {
    menu_data: {},
    name: "one"
    };
    },
    components: {
    menutree: menutree
    },
    props: ["data","calssName"],
    mounted() {
    // console.log(this.$route);
    },
    methods: {
    getImgUrl(icon) {
    return require("@/assets/" + icon);
    }
    }
    };
     
     
    css:
     
    .menutree /deep/ .el-menu-item,
    .menutree /deep/ .el-submenu__title {
    color: #ffffff !important;
    height: 60px;
    line-height: 60px;
    display: flex;
    text-align: left;
    padding: 0;
    img {
    width: 16px;
    height: 16px;
    float: left;
    margin-top: 21px;
    margin-left: 39px;
    }
    span {
    float: left;
    margin-left: 12px;
    }
    }
    .one /deep/ .el-menu {
    background: none;
    }
    .listtxt.menutree /deep/ .el-menu-item,.listtxt.menutree /deep/ .el-submenu__title {
    color: #a6160a !important;
    }
     
    好啦,就到这里了,有不明白的地方可以跟我留言,我是前端菜鸡儿,嘻嘻嘻嘻。

     

     

  • 相关阅读:
    Redis存储对象(序列化和反序列化)
    JAVA中关于set()和get()方法的理解以及使用
    5W1H分析法
    Spring AOP的理解(通俗易懂)。
    Notepad++ 使用步骤,熟练掌握notepad++的使用技巧,无疑会大大提升专业技能。以及快捷键操作
    Int,String,Integer,double之间的类型的相互转换
    Ajax局部刷新和全局刷新的区别
    GET和POST都是什么时候用?
    ajax为什么需要json格式响应数据?
    final fially finalize区别
  • 原文地址:https://www.cnblogs.com/yushihao/p/11759525.html
Copyright © 2011-2022 走看看