目录

非动态渲染的代码:

Home.vue组件

路由配置router.js 

动态渲染菜单项

Home.vue

router.js配置

通过数据库进行菜单动态渲染.....待更新


非动态渲染的代码:

Home.vue组件

<template>
  <div>
    <el-container>
       <el-aside width="200px">
          <el-menu @select="menuClick">
            <el-submenu index="1">
              <template slot="title">
                <i class="el-icon-location"></i>
                <span>导航一</span>
              </template>
                <el-menu-item index="/home/test1">选项1</el-menu-item>
                <el-menu-item index="/home/test2">选项2</el-menu-item>
            </el-submenu>
          </el-menu>
        </el-aside>
        <el-main>
          <router-view/>
        </el-main>
    </el-container>
  </div>
</template>

<script>
export default {
  name: "Home",
  methods: {
    //菜单激活回调
    /**
     * index:选中菜单项的index,在这里我们用作为跳转路径
     * indexPath:选中菜单项的index path
     */
    menuClick(index){
        //路由跳转
        this.$router.push(index)
    },
  
    },
  },
};
</script>

路由配置router.js 

非完整代码,忽略了import 和Vue.use(VueRouter)

const routes = [{
    path: '/'
    ,name: 'Login'
    ,component: Login
  },
  {
    path: '/home'
    ,name: '导航一'
    ,component: Home
    ,children: [{
        path: '/test1'
        ,name: Test1'
        ,component: Test1
      },
      {
        path: '/test2'
        ,name: 'Test2'
        ,component: Test2
      }
    ]
  },
]

 这种方式每次新添加一个菜单项都需要我们去在Hone.vue中添加,然后在router.js配置路由.比较麻烦点.下面我们就将利用vue中的$router获取到router.js中的配置项,然后去动态的渲染Home.vue中的菜单项和子菜单项的信息.这样每次我们只需要修改router.js里面的东西就可以了,不用再去修改Home.vue中的内容了

动态渲染菜单项

Home.vue

使用this.$router.options.routes获取到router.js中各项路由配置的信息,其中的每一个item都是一个路由配置项.

hidden:标识位,表示是否渲染该项路由信息

<template>
  <div>
    <el-container>
      <el-header class="homeHeader">
        <div class="title">人事管理</div>
        <el-dropdown class="userInfo" @command="commandHandler">
          <span class="el-dropdown-link">
            {{ user.name }}<i><img :src="user.userface" alt="" /></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <!-- 每个下拉框的item中的command相当于id一样用于标记每个item -->
            <el-dropdown-item command="userinfo">个人中心</el-dropdown-item>
            <el-dropdown-item command="setting">设置</el-dropdown-item>
            <el-dropdown-item command="logout" divided>
              退出登录</el-dropdown-item
            ><!--divided表示分割线 -->
          </el-dropdown-menu>
        </el-dropdown>
      </el-header>

      <el-container>
        <el-aside width="200px">
          <el-menu @select="menuClick">
            <el-submenu index="1" v-for="(item,index) in this.$router.options.routes" :key="index" v-if="!item.hidden">
              <template slot="title">
                <i class="el-icon-location"></i>
                <span>{{item.name}}</span>
              </template>
                <el-menu-item :index="child.path" v-for="(child,indexj) in item.children" :key="indexj">{{child.name}}</el-menu-item>
            </el-submenu>
          </el-menu>
        </el-aside>
        <el-main>
          <router-view/>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
export default {
  name: "Home",
  methods: {
    //菜单激活回调
    /**
     * index:选中菜单项的index,在这里我们用作为跳转路径
     * indexPath:选中菜单项的index path
     */
    menuClick(index){
        this.$router.push(index)
    },
  },
};
</script>

router.js配置

const routes = [{
    path: '/'
    ,name: 'Login'
    ,component: Login
    ,hidden:true
  },
  {
    path: '/home'
    ,name: '导航一'
    ,component: Home
    ,hidden:false   //此处的hidden只是个标记相当于bool flag,并不会把该路由隐藏
    ,children: [{
        path: '/test1'
        ,name: '选项一'
        ,component: Test1
      },
      {
        path: '/test2'
        ,name: '选项二'
        ,component: Test2
      }
    ]
  },
]

通过数据库进行菜单动态渲染.....待更新

代码优化v-for  v-if同时使用性能不太好

上面的是同时使用v-for和v-if,下面这个优化后的代码通过计算属性完成对this.$router.options.routes的过滤,将结果再给v-for使用,

<template>
  <div>
    <el-container>
      <el-header class="homeHeader">
        <div class="title">人事管理</div>
        <el-dropdown class="userInfo" @command="commandHandler">
          <span class="el-dropdown-link">
            {{ user.name }}<i><img :src="user.userface" alt="" /></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <!-- 每个下拉框的item中的command相当于id一样用于标记每个item -->
            <el-dropdown-item command="userinfo">个人中心</el-dropdown-item>
            <el-dropdown-item command="setting">设置</el-dropdown-item>
            <el-dropdown-item command="logout" divided>
              退出登录</el-dropdown-item
            ><!--divided表示分割线 -->
          </el-dropdown-menu>
        </el-dropdown>
      </el-header>

      <el-container>
        <el-aside width="200px">
          <el-menu  router>
            <el-submenu index="1" v-for="(item,index) in menus" :key="index" >
              <template slot="title">
                <i class="el-icon-location"></i>
                <span>{{item.name}}</span>
              </template>
                <el-menu-item :index="child.path" v-for="(child,indexj) in item.children" :key="indexj">{{child.name}}</el-menu-item>
            </el-submenu>
          </el-menu>
        </el-aside>
        <el-main>
          <router-view/>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      //存入浏览器的本地session域中
      user: JSON.parse(window.sessionStorage.getItem("user")),
    };
  }, //data-end
  computed:{
    //在计算属性这里进行了过滤(相当于使用了v-if),然后再将过滤后的值给v-for使用
      menus(){
        let arr=[''];
        arr = this.$router.options.routes.filter(item=>{
          return item.hidden==false;
        })
        console.log(arr);
        return arr;
      }
  },
  methods: {
    //菜单激活回调
    /**
     * index:选中菜单项的index,在这里我们用作为跳转路径
     * indexPath:选中菜单项的index path
     * 如果给menu配置一个router属性,就不用写menuClick这个点击事件了:router:会自动将index作为跳转路径进行跳转
     */
    // menuClick(index){
    //     this.$router.push(index)
    // },
    commandHandler(cmd) {
      if (cmd == "logout") {
        //confirm确定框
        this.$confirm("确认退出登录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            //确认时触发

            //向后端发送/logout
            this.getRequest("/logout");
            window.sessionStorage.removeItem("user"); //清空sessionStorage中的值
            this.$router.replace("/"); //回到登录页面
          })
          .catch(() => {
            //取消时触发
            this.$message({
              type: "info",
              message: "已取消操作",
            });
          });
      }
    },
  },
};
</script>

<style>
.homeHeader {
  background-color: #409eff;
  display: flex;
  /* 竖直方向上居中 */
  align-items: center;
  /*在弹性盒对象的 <div> 元素中的各项周围留有空白*/
  justify-content: space-between;
  padding: 0px 15px;
  box-sizing: border-box;
}

/* header中的'人事管理'字体设置 */
.homeHeader .title {
  font-size: 30px;
  font-family: 华文行楷;
  color: #ffffff;
}

/* 在鼠标放在右上角的抽屉式dropdown时,鼠标变为手指 */
.homeHeader .userInfo {
  cursor: pointer;
}

.el-dropdown-link img {
  width: 48px;
  height: 48px;
  border-radius: 24px;
  margin-left: 8px;
}
.el-dropdown-link {
  display: flex;
  align-items: center;
}
</style> 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐