Vue 组件库Element布局容器动态生成侧边栏。

为了让大家可以继续看下去,代码展示效果我先给出来
https://htmlzhoyan.github.io/ElementUi/#/ele/elc/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86
我这里要实现 Vue 2.0 的桌面端组件库Element中的侧边栏内容动态生成,换句话说,我并不知道侧边栏菜单里会有多少个子选项,所以我这样设计
目录结构如下:

vue布局

我这边使用了组件里面再次调用组件的方法。
所以 我这样先声明个组件 eleTemplate.vue

<template>
  <div class="navMenu">

    <label v-for="navMenu in navMenus">
      <router-link :to="{ name: 'elc', params: {id:navMenu.entity.name} }">
        <el-menu-item v-if="navMenu.childs==null&&navMenu.entity&&navMenu.entity.state==='ENABLE'"
                      :key="navMenu.entity.id" :data="navMenu" :index="navMenu.entity.name" :route="navMenu.entity.value">
          <i :class="navMenu.entity.icon"></i>
          <span slot="title">{{navMenu.entity.alias}}</span>
        </el-menu-item>
      </router-link>


      <el-submenu v-if="navMenu.childs&&navMenu.entity&&navMenu.entity.state==='ENABLE'"
                  :key="navMenu.entity.id" :data="navMenu" :index="navMenu.entity.name">
        <template slot="title">
          <i :class="navMenu.entity.icon"></i>
          <span> {{navMenu.entity.alias}}</span>
        </template>
        <NavMenu :navMenus="navMenu.childs"></NavMenu>
      </el-submenu>
    </label>

  </div>
</template>

<script>
  export default {
    name: 'NavMenu',
    props: ['navMenus'],
    data() {
      return {}
    },
    methods: {}
  }
</script>

<style scoped>
    a{
      text-decoration:none
    }
</style>



然后我在父组件里调用它,这里我使用了router-view来展示子路由里的页面效果,同时我为了实现路由进来的时候去触发侧边栏的指向,我在el-menu里添加了default-active

<template lang="html">
  <div class="">
    <el-container style="height: 500px; border: 1px solid #eee">
  <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
    <!--左侧菜单组件-->
       <el-menu
         :default-active="isId"
         @select="handleSelect"
         class="el-menu-vertical-demo"
         background-color="#F0F6F6"
         text-color="#3C3F41"
         active-text-color="#f60">
         <NavMenu :navMenus="totalList"></NavMenu>
       </el-menu>
     </el-aside>

<el-container>
  <el-main>
   <router-view></router-view>
  </el-main>
</el-container>
</el-container>
  </div>

</template>

<script>
import config from './config'
import NavMenu from './eleTemplate';
export default {
  data() {
    return{
      totalList:[],
      isId:"权限管理"
    }

  },
  methods: {
    handleSelect(key,keyPath){
      console.log(key,keyPath)
    }
  },
  components: {
                NavMenu
    },
   beforeRouteEnter (to, from, next) {
      console.log("我从哪里来",to.params.id,from)
      var self = this
     
      next(vm=>{

        vm.isId = to.params.id
      
      })

   
    },
 watch:{
     $route(to,from){
        this.isId = to.params.id
     }
   },
  created(){
    this.totalList = config.childs
  },
}
</script>

<style lang="css">
</style>

其中 我为了模拟数据,引入config.js,后期是通过后端返回的数据来实现的

let config = {
    "entity": null,
    "childs": [
        {
            "entity": {
                "id": 1,
                "parentMenuId": 0,
                "name": "系统管理",
                "icon": "el-icon-message\r\n",
                "alias": "系统管理",
                "state": "ENABLE",
                "sort": 0,
                "value": null,
                "type": "NONE",
                "createUserId": 1
            },
            "childs": [
                {
                    "entity": {
                        "id": 3,
                        "parentMenuId": 1,
                        "name": "权限管理",
                        "icon": "el-icon-loading",
                        "alias": "权限管理",
                        "state": "ENABLE",
                        "sort": 0,
                        "value": "/system/auth",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                },
                {
                    "entity": {
                        "id": 4,
                        "parentMenuId": 1,
                        "name": "角色管理",
                        "icon": "el-icon-bell",
                        "alias": "角色管理",
                        "state": "ENABLE",
                        "sort": 1,
                        "value": "/system/role",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                },
                {
                    "entity": {
                        "id": 2,
                        "parentMenuId": 1,
                        "name": "菜单管理",
                        "icon": "el-icon-edit",
                        "alias": "菜单管理",
                        "state": "ENABLE",
                        "sort": 2,
                        "value": "/system/menu",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                },
                {
                    "entity": {
                        "id": 5,
                        "parentMenuId": 1,
                        "name": "分组管理",
                        "icon": "el-icon-mobile-phone\r\n",
                        "alias": "分组管理",
                        "state": "ENABLE",
                        "sort": 3,
                        "value": "/system/group",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                }
            ]
        },
        {
            "entity": {
                "id": 6,
                "parentMenuId": 0,
                "name": "用户管理",
                "icon": "el-icon-news",
                "alias": "用户管理",
                "state": "ENABLE",
                "sort": 1,
                "value": null,
                "type": "NONE",
                "createUserId": 1
            },
            "childs": [
                {
                    "entity": {
                        "id": 7,
                        "parentMenuId": 6,
                        "name": "帐号管理",
                        "icon": "el-icon-phone-outline\r\n",
                        "alias": "帐号管理",
                        "state": "ENABLE",
                        "sort": 0,
                        "value": "",
                        "type": "NONE",
                        "createUserId": 1
                    },
                    "childs": [
                        {
                            "entity": {
                                "id": 14,
                                "parentMenuId": 7,
                                "name": "邮箱管理",
                                "icon": "el-icon-sold-out\r\n",
                                "alias": "邮箱管理",
                                "state": "ENABLE",
                                "sort": 0,
                                "value": "/content/email",
                                "type": "LINK",
                                "createUserId": 1
                            },
                            "childs": null
                        },
                        {
                            "entity": {
                                "id": 13,
                                "parentMenuId": 7,
                                "name": "密码管理",
                                "icon": "el-icon-service\r\n",
                                "alias": "密码管理",
                                "state": "ENABLE",
                                "sort": 1,
                                "value": "/content/pass",
                                "type": "LINK",
                                "createUserId": 1
                            },
                            "childs": null
                        }
                    ]
                },
                {
                    "entity": {
                        "id": 8,
                        "parentMenuId": 6,
                        "name": "积分管理",
                        "icon": "el-icon-picture",
                        "alias": "积分管理",
                        "state": "ENABLE",
                        "sort": 1,
                        "value": "/user/integral",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                }
            ]
        },
        {
            "entity": {
                "id": 9,
                "parentMenuId": 0,
                "name": "内容管理",
                "icon": "el-icon-rank",
                "alias": "内容管理",
                "state": "ENABLE",
                "sort": 2,
                "value": null,
                "type": "NONE",
                "createUserId": 1
            },
            "childs": [
                {
                    "entity": {
                        "id": 10,
                        "parentMenuId": 9,
                        "name": "分类管理",
                        "icon": "el-icon-printer",
                        "alias": "分类管理",
                        "state": "ENABLE",
                        "sort": 0,
                        "value": "/content/classify",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                },
                {
                    "entity": {
                        "id": 11,
                        "parentMenuId": 9,
                        "name": "文章管理",
                        "icon": "el-icon-star-on",
                        "alias": "文章管理",
                        "state": "ENABLE",
                        "sort": 1,
                        "value": "/content/article",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                },
                {
                    "entity": {
                        "id": 12,
                        "parentMenuId": 9,
                        "name": "评论管理",
                        "icon": "el-icon-share",
                        "alias": "评论管理",
                        "state": "ENABLE",
                        "sort": 2,
                        "value": "/content/comment",
                        "type": "LINK",
                        "createUserId": 1
                    },
                    "childs": null
                }
            ]
        }
    ]
}
export default config


和附加内容elc.vue,来填充contain内容。我实现了tab选项的增和删,同时,添加了如果重复去跳转之前添加的tab,删除tab之前有bug,这次修改后,通过监听路由改动,保证路由实时改动,侧边栏也可以进行改变

<template lang="html">
  <div>
    <div style="margin-bottom: 20px;">

    </div>
    
    <el-tabs v-model="editableTabsValue2" type="card" closable @tab-remove="removeTab">
  <el-tab-pane
    v-for="(item, index) in editableTabs2"
    :key="item.name"
    :label="item.title"
    :name="item.name"
  >
    {{item.title}}
  </el-tab-pane>
  </el-tabs>

    <el-table :data="tableData">
    <el-table-column prop="date" label="日期" width="140">
    </el-table-column>
    <el-table-column prop="name" label="姓名" width="120">
    </el-table-column>
    <el-table-column prop="address" label="地址">
    </el-table-column>
  </el-table>
</div>
  
</template>

<script>
export default {
  data(){
    return {
      btn:true,
      item:{
        date: '2018-11-11',
        name: 'OnePiece',
        address: '郑州市高新区推进城',
        
      },
      editableTabsValue2: '2',
      editableTabs2: [],
      tabIndex: 0,
      tableData: [],
      totalList:[],

    }
  },
  methods:{
    addTab(targetName) {
      this.btn= true
        this.editableTabs2.forEach((v,k)=>{
         
          if(v.title==targetName){
           
            this.btn = false;
            this.editableTabsValue2 = v.name
          }
        })
        if(this.btn){
          let newTabName = ++this.tabIndex + '';
        this.editableTabs2.push({
          title: targetName,
          name: newTabName,
          content: targetName
        });
        this.editableTabsValue2 = newTabName;
        }
        
      },
       removeTab(targetName) {
        let tabs = this.editableTabs2;
        let activeName = this.editableTabsValue2;
       
        if (activeName === targetName) {
          tabs.forEach((tab, index) => {
            if (tab.name === targetName) {
              let nextTab = tabs[index + 1] || tabs[index - 1];
              if (nextTab) {
                activeName = nextTab.name;
                 this.$router.push({
                  name: "elc",
                  params: {
                    id: nextTab.title
                  }
              });
              }
            }
          });
        }
        
        this.editableTabsValue2 = activeName;

        this.editableTabs2 = tabs.filter(tab => tab.name !== targetName);
       
      }
    },
  created () {
    this.tableData = Array(20).fill(this.item);

  },
  beforeRouteEnter (to, from, next) {
      console.log("我从哪里来",to.params.id,from)
      var self = this
     
      next(vm=>{
      vm.item.name =to.params.id;
       vm.addTab(to.params.id);
      })

   
    },
  watch:{
     $route(to,from){
         this.item.name =this.$route.params.id;
         this.addTab(to.params.id);
     }
   },
}
</script>

<style lang="css">
</style>



路由的内容


路由代码

这样我就实现了,可以根据后端返回数据来动态加载数据。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容