vue.js实现二级菜单效果


Posted in Javascript onOctober 19, 2019

本文实例为大家分享了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组件学习教程进行学习。

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

Javascript 相关文章推荐
javascript语言结构小记(一)
Sep 10 Javascript
关于JS管理作用域的问题
Apr 10 Javascript
jquery中的on方法使用介绍
Dec 29 Javascript
一行命令搞定node.js 版本升级
Jul 20 Javascript
继续学习javascript闭包
Dec 03 Javascript
手机图片预览插件photoswipe.js使用总结
Aug 25 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 Javascript
JavaScript获取当前时间向前推三个月的方法示例
Feb 04 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
Apr 09 Javascript
jQuery实现的点击标题文字切换字体效果示例【测试可用】
Apr 26 jQuery
Vue二次封装axios为插件使用详解
May 21 Javascript
深入理解令牌认证机制(token)
Aug 22 Javascript
vue实现多级菜单效果
Oct 19 #Javascript
vue.js实现三级菜单效果
Oct 19 #Javascript
vue.js实现只能输入数字的输入框
Oct 19 #Javascript
Vue数字输入框组件的使用方法
Oct 19 #Javascript
微信小程序实现禁止分享代码实例
Oct 19 #Javascript
Vue.js组件props数据验证实现详解
Oct 19 #Javascript
Vue.js组件使用props传递数据的方法
Oct 19 #Javascript
You might like
一些常用的php函数
2006/12/06 PHP
PHP+mysql+ajax轻量级聊天室实现方法详解
2016/10/17 PHP
Expandable &quot;Detail&quot; Table Rows
2007/08/29 Javascript
Mootools 1.2教程 函数
2009/09/15 Javascript
IE和firefox浏览器的event事件兼容性汇总
2009/12/06 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
javascript动态创建表格及添加数据实例详解
2015/05/13 Javascript
JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
2016/08/26 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
2016/10/28 Javascript
浅谈jquery页面初始化的4种方式
2016/11/27 Javascript
JS实现闭包中的沙箱模式示例
2017/09/07 Javascript
Angular5中调用第三方库及jQuery的添加的方法
2018/06/07 jQuery
微信小程序 checkbox使用实例解析
2019/09/09 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
js实现简单商品筛选功能
2021/02/02 Javascript
[05:39]2014DOTA2西雅图国际邀请赛 淘汰赛7月14日TOPPLAY
2014/07/14 DOTA
[01:38]完美世界高校联赛决赛花絮
2018/12/02 DOTA
python中用logging实现日志滚动和过期日志删除功能
2019/08/20 Python
Python学习笔记之集合的概念和简单使用示例
2019/08/22 Python
tensorflow入门:tfrecord 和tf.data.TFRecordDataset的使用
2020/01/20 Python
tensorflow多维张量计算实例
2020/02/11 Python
Python字符串格式化f-string多种功能实现
2020/05/07 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
联想法国官方网站:Lenovo法国
2018/10/18 全球购物
探索欧洲最好的品牌:Bombinate
2019/06/14 全球购物
什么是接口(Interface)?
2013/02/01 面试题
医药营销专业个人自荐信
2013/09/29 职场文书
医学生自荐信
2013/12/03 职场文书
骨干教师培训方案
2014/05/06 职场文书
说明书怎么写
2014/05/06 职场文书
大学生简短的自我评价
2014/09/12 职场文书
2014年幼儿园小班工作总结
2014/12/04 职场文书
拾金不昧感谢信
2015/01/21 职场文书
食堂管理制度范本
2015/08/04 职场文书
解除租赁合同协议书
2016/03/21 职场文书