vue.js实现二级菜单效果

本文实例为大家分享了vue.js实现二级菜单效果的具体代码,供大家参考,具体内容如下

主要是对二级菜单和当前点击的处理:

点击导航时,如果有二级菜单,就切换二级菜单显示状态(显示或者关闭),如果没有二级菜单,就变色,表示页面处于当前位置,并且导航中最多只能有一个菜单变色。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>这是一个v-for的导航条</title>
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script>
 <link rel="stylesheet" href="nav.css" >
</head>
<body>
<div id="pages">
 <ul id="side-menu">
 <li class="menu-unit" v-for="menu in menus">
  <a id="menu-url" v-bind:href="menu.url"
   v-bind:class="{ 'menu-active': menu.active && !menu.secondMenus}"
   v-on:click="showToggle(menu)"
  >
  <i v-bind:class="menu.icon"></i>
  <span>{{ menu.text }}</span>
  <i v-if="menu.downIcon" v-bind:class="menu.downIcon"></i>
  </a>
  <ul id="side-second-menu" v-if="menu.secondMenus && menu.active">
  <li v-for="secMenu in menu.secondMenus" v-on:click="showToggle(menu, secMenu)">
   <a v-bind:href="secMenu.url" rel="external nofollow"
    v-bind:class="{ 'menu-active': secMenu.active }">
   <span>{{ secMenu.text }}</span>
   </a>
  </li>
  </ul>
 </li>
 </ul>
</div>

<script>
 var vm = new Vue({
 el: '#side-menu',
 data: {
  menus: [
  {
   text: '首页',
   icon: 'glyphicon glyphicon-apple',
   active: false
  },
  {
   text: '文档',
   // url: 'https://www.baidu.com/',
   icon: 'glyphicon glyphicon-book',
   active: false
  },
  {
   text: '引导页',
   // url: 'https://www.baidu.com/',
   icon: 'glyphicon glyphicon-send',
   active: false
  },
  {
   text: '权限测试页',
   icon: 'glyphicon glyphicon-lock',
   downIcon: 'glyphicon glyphicon-menu-down',
   active: false,
   secondMenus: [
   {text: '页面权限', url: '#', active: false},
   {text: '权限指令', url: '#', active: false},
   ]
  },
  {
   text: '图标',
   icon: 'glyphicon glyphicon-pawn',
   active: false,
   // url: 'https://www.baidu.com/'
  },
  ]
 },
 methods: {
  showToggle: function (menu, secMenu) {
  // 如果传入了二级菜单
  if (secMenu) {
   secMenu.active = true;
   // 更新menus数据
   this.refreshMenuTree(this.menus, menu, secMenu);
  } else {
   if (menu.secondMenus) {
   menu.active = !menu.active;
   } else {
   menu.active = true;
   // 更新menus数据
   this.refreshMenuTree(this.menus, menu, secMenu);
   }
  }
  },

  /**
  * 解释:对于菜单栏active置为true的逻辑,可以简化为,我点击谁谁就active,其他的菜单项active都变为
  * false。但特殊情况为二级菜单,二级菜单点击后自己的active变为true,但父菜单项的active不能变false。
  * 所以问题简化为:
  * 1. 点击的菜单项的active变为true
  * 2. 遍历整个菜单的所有数据项,不等于我点击的这个菜单项的active都变为false
  * (但二级菜单要考虑其父菜单项不能变false,即除了我点击的这个和我的父菜单项外都变false)
  *
  * 关键问题即:用树的遍历解决菜单所有数据项的遍历和active取反,即对于被遍历的每个菜单项来说,
  * 只要不等于我传入的一级菜单和二级菜单,active就变成false
  *
  * 整体逻辑即:menus中的数据项,进行遍历,如果不等于传入的menu或者secMenu则直接置为false
  * @param menus 包含menu数据项的数组,如一级菜单数组,二级菜单数组
  * @param menu 应该激活的一级菜单项
  * @param secMenu 应该激活的二级菜单项
  */
  refreshMenuTree(menus, menu, secMenu) {
  // 开始遍历
  menus.forEach(function (item) {
   // 如果菜单项不等于传入的一级菜单项或二级菜单项,则active置为false
   if (!(item === menu || item === secMenu || (item.secondMenus && item.active))) {
   item.active = false;
   }

   // 如果菜单项包含二级菜单列表,则遍历此列表
   if (item.secondMenus) {
   this.refreshMenuTree(item.secondMenus, menu, secMenu);
   }
   // 使用.bind(this)给函数的this绑定为外层的作用域,要不然this.refreshMenuTree方法取不到
  }.bind(this));
  },

 }
 })
</script>

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>

</body>
</html>

更多教程点击《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Vue实现自定义下拉菜单功能

    先看例子,后面有对用到的知识点的总结 效果图: 实现代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件练习</title> <link rel="stylesheet" type="text/css" href="component.c

  • vue实现多级菜单效果

    本次记录基于iview3框架实现多级菜单+vue router实现页面切换 方法一: 使用Tree 树形控件,官方文档 以官方demo为例,数据中添加URL属性,用于路由跳转,正式项目中该tree控件的数据由后端给出,需要注意的是后端给出的URL跳转地址最前一定要看清有没有"/" ,如果没有自己手动加或后端改,没有这个"/" 斜杠会导致路由跳转失败. 思路:根据官方文档里面写用on-select-change事件返回当前已选中的节点数组.当前项,就利用返回的当前项数

  • Vue.js组件tree实现无限级树形菜单

    分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望分享下. 代码看这里喽: html代码: <div class="tree"> <nav class='navbar'> <ul class='nav nav-stacked'> <template v-for='item in menus'> <li role='presentation' v-if='!item.c

  • 详解Vue用自定义指令完成一个下拉菜单(select组件)

    这次分享的是关于Vue自定义指令的使用方法,学习完基础后我们再来实战完成一个下拉列表,废话不多说,直接上干货 基本用法 //全局注册 Vue.directive('my-directive', { // 指令选项 }) // 局部注册 var app = new Vue({ el: '#app' directives: { 'my-directive': { // 指令选项 } }) 相信对Vue比较熟悉的人看完都知道,directive的写法与组件 基本类似,只是方法名由component改为

  • vue下拉菜单组件(含搜索)的实现代码

    之前也写过这个小组件,最近遇到select下加搜索的功能,所以稍微完善一下. 效果图: 子组件 dropdown.vue <template> <div class="vue-dropdown default-theme"> <div class="cur-name" @click="isShow =! isShow">{{itemlist.cur.name}}</div> <div clas

  • 浅谈Vue.js中如何实现自定义下拉菜单指令

    我们利用  Vue.js 的自定义指令能力,来实现一个自定义下拉菜单功能.描述如下: 点击按钮,弹出下拉菜单. 点击下拉菜单之外的区域,关闭下拉菜单. 1基础版 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="styleshee

  • 基于vue.js实现侧边菜单栏

    侧边菜单栏应该是很多项目里必不可少的 自己手写了一个 下面是效果图 下面就说一下实现的过程 还是比较简单的 首先导入一下需要的文件 <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.min.css" rel="external nofollow" > <link rel="stylesheet" typ

  • vue-router+vuex addRoutes实现路由动态加载及菜单动态加载

    此案例主要实现了一个功能是,在vue实例首次运行时,在加载了login和404两个路由规则,登录成功后,根据登录用户角色权限获取该角色相应菜单权限,生成新的路由规则添加进去. 做过后台管理系统都一定做过这个功能,在对菜单权限进行粗粒度权限控制的时候,通过角色获取菜单后,异步生成菜单,所以一开始拿到需求的时候,我也以为这和平常的没什么不同,不过做起来就发现了很多问题, 1.vue-router的实例,在new vue实例的时候,就加载了,且必须加载,这个时候,登录路由一定要加载,可是这个时候没有登

  • Vue.js 递归组件实现树形菜单(实例分享)

    最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单. 项目结构: main.js 作为入口,很简单: import Vue from 'vue' Vue.config.debug = true import main from './components/main.vue' new Vue({ el: '#app', render: h => h(main) }) 它引入了一个组件 main.vue: <template> <div class="tree-m

  • Vue.js下拉菜单组件使用方法详解

    本文实例为大家分享了Vue.js下拉菜单组件的具体实现代码,供大家参考,具体内容如下 效果 #### 入口页面 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scal

随机推荐