vue element 左侧动态树形导航 Demo




因为官方给的例子是死的数据,全都用html写出来很多,所以想通过数据去展示nav,于是简单踩了下坑。

第一种:折叠式 nav code

<template>
  <el-container class="app-default-layout">
    <el-aside class="app-left-nav bg-gredient-indigo" :style="{'max-width': drawer ? '70px' : '300px'}">
      <el-menu
        :default-active="activeIndex"
        @select="handleSelect"
        router
        class="el-menu-vertical-nav color-white"
        text-color="#FFFFFF"
        active-text-color="#FFFFFF"
        :background-color="drawer ? '#14191F' : 'transparent'"
        :show-timeout="50"
        :hide-timeout="50"
        :collapse="drawer">
        <template v-for="(subMenu, subIndex) in navList">
          <!--只有一级菜单-->
          <el-menu-item v-if="!subMenu.children" :key="subIndex" :index="subMenu.to">
            <v-icon color="#FFFFFF" class="mr-1" v-html="subMenu.icon"></v-icon>
            <span slot="title">{{ subMenu.title }}</span>
          </el-menu-item>
          <!-- 多级菜单 -->
          <el-submenu v-else :index="subIndex + ''" :key="subIndex">
            <template slot="title">
              <i class="el-icon-location"></i>
              <span>{{ subMenu.title }}</span>
            </template>
            <el-menu-item-group>
              <span slot="title" v-show="drawer">{{ subMenu.title }}</span>
              <template v-for="(menu, index) in subMenu.children">
                <el-menu-item
                  v-if="(menu.title === 'Projects' && isAdminOrLTE) || menu.title !== 'Projects'"
                  :index="menu.to"
                  :key="index"
                >
                  <v-icon color="#FFFFFF" class="mr-1" v-html="menu.icon"></v-icon>
                  {{ menu.title }}
                </el-menu-item>
              </template>
            </el-menu-item-group>
          </el-submenu>
        </template>
      </el-menu>
    </el-aside>
    <el-container class="app-container-box" :style="{'padding-left': drawer ? '70px' : '300px'}">
      <el-header class="d-flex justify-space-between align-center app-header-nav" :style="{'left': drawer ? '70px' : '300px'}">
        <el-button class="side-nav-btn header-nav-btn" :icon="drawer ? 'el-icon-s-unfold side-nav-icon' : 'el-icon-s-fold side-nav-icon'" circle @click="changeSideStatus()"></el-button>
        <div class="d-flex justify-end align-center">
          <v-icon style="max-width: 24px;" class="mr-2">account_circle</v-icon>
          {{ $store.state.auth.user.user_name }}
          <el-button class="logout-btn header-nav-btn ml-2" circle @click="logout()">
            <v-icon>exit_to_app</v-icon>
          </el-button>
        </div>
      </el-header>
      <el-main class="bg-gredient-lightBlue" data-app="true" style="margin-top: 45px;">
          <nuxt />
      </el-main>
      <el-footer style="height: 26px; padding-top: 3px;">
        <p style="text-align: center;" class="mb-0">ARES &copy; 2019</p>
      </el-footer>
    </el-container>
  </el-container>
</template>

<script>
export default {
  data () {
    return {
      drawer: false,
      navList: [
        { icon: 'apps', title: 'Dashboard', to: '/' },
        { icon: 'description', title: 'BKMs', to: '/bkms' },
        // { icon: 'date_range', title: 'Plans', to: '/plans', checkProject: true },
        { icon: 'date_range', title: 'Plans', to: '/plans' },
        // { icon: 'event_note', title: 'Memo', to: '/memos', checkProject: true },
        { icon: 'assignment', title: 'Engineer', to: '/engineer' },
        { icon: 'assignment', title: 'HR', to: '/hr' },
        { icon: 'bug_report', title: 'Tracking', to: '/trackings' },
        { icon: 'view_list', title: 'Resources', to: '/resources' },
        { icon: 'event_note', title: 'Project', to: `/projects` },
        // { icon: 'folder_open', title: 'FW', to: '/fws', checkProject: true }
        {
          icon: 'show_chart',
          title: 'ARES Rept.',
          children: [
            { icon: 'list_alt', title: 'Defects', to: '/defects' },
            { icon: 'list_alt', title: 'Defects Classification', to: '/defectsClassification' },
            { icon: 'storage', title: 'Projects', to: '/projectares' },
            { icon: 'poll', title: 'Defect Flight Pattern', to: '/defectFlightPattern' }
          ]
        },
        {
          icon: 'account_circle',
          title: 'Admin',
          children: [
            // { icon: 'event_note', title: 'Projects', to: '/projects' },
            { icon: 'view_agenda', title: 'Progress', to: '/progress' },
            { icon: 'people', title: 'Customers', to: '/customers' },
            { icon: 'assessment', title: 'Patterns', to: '/patterns' },
            { icon: 'face', title: 'Users', to: '/users' },
            { icon: 'local_offer', title: 'Tags', to: '/tags' },
            { icon: 'timeline', title: 'Timeline', to: '/timeline' },
            { icon: 'assignment', title: 'Resource Types', to: '/resourcetypes' },
            { icon: 'schedule', title: 'Schedule', to: '/schedule' }
          ]
        }
      ],
      activeIndex: '/'
    }
  },
  watch: {
    '$route' () {
      this.handleSelect(this.activeIndex)
    }
  },
  methods: {
    changeSideStatus () {
      this.drawer = !this.drawer
    },
    handleSelect (index) {
      this.activeIndex = index
    }
  },
  mounted () {
    this.activeIndex = this.$route.matched[0].path || '/'
  }
}
</script>

<style lang="stylus">
.app-default-layout {
  min-width: 100vh;
  .app-left-nav {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    z-index: 100;
    overflow-x: hidden;
    overflow-y: auto;
    transition: all .1s;
  }
  .el-menu-vertical-nav {
    width: 70px;
    border: 0;
    .el-menu-item:hover,
    .el-submenu .el-submenu__title:hover {
      background-color: hsla(0, 0%, 100%, .08) !important;
    }
    .el-menu-item.is-active {
      background-color: hsla(0, 0%, 100%, .2) !important;
    }
    .el-menu-item-group__title {
      padding-top: 0;
      padding-bottom: 0;
    }
  }
  .el-menu-vertical-nav:not(.el-menu--collapse) {
    width: 300px;
  }
  .app-container-box {
    transition: all .1s;
    min-height: 100vh;
  }
  .app-header-nav {
    position: fixed;
    top: 0;
    right: 0;
    height: 45px !important;
    z-index: 100;
    background-color: #f5f5f5;
    transition: all .1s;
    box-shadow: 0 2px 4px -1px rgba(0,0,0,.2), 0 4px 5px 0 rgba(0,0,0,.14), 0 1px 10px 0 rgba(0,0,0,.12);
  }
  .header-nav-btn {
    border: 0;
    padding: 0;
    background: transparent;
    &:focus {
      background: transparent;
      color: #606266;
    }
    &:hover {
      background: #DCDCDC;
      color: #606266;
    }
  }
  .side-nav-btn {
    width: 35px;
    height: 35px;
    max-width: 35px;
    i.side-nav-icon {
      font-size: 26px;
    }
  }
  .logout-btn {
    width: 30px;
    height: 30px;
    max-width: 30px;
  }
}
.el-menu--vertical {
  .el-menu-item:hover {
    background-color: hsla(0, 0%, 100%, .1) !important;
  }
  .el-menu-item.is-active {
    background-color: hsla(0, 0%, 100%, .2) !important;
  }
}
</style>

第二种:普通 nav 效果图

效果图

code

<div class="nav-list">
      <el-row class="tac">
        <el-col>
          <el-menu
            default-active="/"
            router
            class="el-menu-vertical-demo"
            background-color="#545c64"
            text-color="#fff"
            active-text-color="#ffd04b"
          >
            <div v-for="(subMenu, subIndex) in navList" :key="subIndex">
              <!--只有一级菜单-->
              <el-menu-item v-if="!subMenu.children" :index="subMenu.to">
                <i class="el-icon-location"></i>
                {{ subMenu.title }}
              </el-menu-item>
              <!-- 多级菜单 -->
              <el-submenu v-else :index="subIndex + ''">
                <template slot="title">
                  <i class="el-icon-location"></i>
                  <span>{{ subMenu.title }}</span>
                </template>
                <el-menu-item-group>
                  <el-menu-item
                    v-for="(menu, index) in subMenu.children"
                    :index="menu.to"
                    :key="index"
                  >
                    <i class="el-icon-location"></i>
                    {{ menu.title }}
                  </el-menu-item>
                </el-menu-item-group>
              </el-submenu>
            </div>
          </el-menu>
        </el-col>
      </el-row>
    </div>

js

data() {
    return {
      navList: [
        {
          icon: 'apps',
          title: 'Index',
          children: [
            {
              icon: 'apps',
              title: 'page1',
              to: '/ac'
            },
            {
              icon: 'apps',
              title: 'page2',
              to: '/'
            }
          ]
        },
        { icon: 'assignment', title: 'BKMs', to: '/acb' },
        {
          icon: 'apps',
          title: 'demo',
          children: [
            {
              icon: 'apps',
              title: 'demo1',
              to: '/accb'
            }
          ]
        }
      ]
    }
  },
  • 首先想让他变成路由导航,el-menu 一定要添加 router 属性,此时他就会根据 el-menu-item 中的 index 去 push router
  • 需要注意的是:多级菜单时,虽然 el-submenu 并不想让他跳转,但是一定要加上 index 属性(可以放index就行,保证唯一性)
  • index 属性的值一定要是 string ,比如 我的 subIndex 就要拼接个 ‘’ ,达到转换字符串的目的
  • 我的 Demo 只有两层,如果需要更多层,继续嵌套就可以了。

觉得有帮助的小伙伴右上角点个赞~

在这里插入图片描述

扫描上方二维码关注我的订阅号~

发布了119 篇原创文章 · 获赞 74 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/q95548854/article/details/93468772