应用el-tabs模拟nav menu组件
栏目: JavaScript · 发布时间: 6年前
内容简介:目前在做的项目遇到如图所示需求。 本是个简单的menu, 但是我偏选了el-tabs组件为基础进行改写,花了好多时间,也踩了不少坑。但总算是完成啦!特此记录填坑记录。routerMap结构为简单的二维数组,根据需求,最多二维,不考虑更深的嵌套及外链情况;路由详情请参考路由配置项及示例。
目前在做的项目遇到如图所示需求。 本是个简单的menu, 但是我偏选了el-tabs组件为基础进行改写,花了好多时间,也踩了不少坑。但总算是完成啦!特此记录填坑记录。
routerMap结构为简单的二维数组,根据需求,最多二维,不考虑更深的嵌套及外链情况;
路由详情请参考路由配置项及示例。
注册组件Navbar
这就不说了。。
应用router数据生成el-tabs
获取router数据
computed: { routes() { return this.$router.options.routes } } 复制代码
渲染el-tabs,将非隐藏的router展示出来
<el-tabs v-model="activeName" @tab-click="handleClick"> <el-tab-pane v-for="route in routes" class="slideInUp" v-if="!route.hidden&&route.children" :name="route.path" :label= "route.name" > </el-tab-pane> </el-tabs> 复制代码
说到这还没什么难得,接下来问题来了。
问题一:动态渲染 label
为 icon+text
label
作为 el-tab-pane
的属性接收的是字符串,但是我要的label,不仅要文字,还要在上面加上我的 icon
. 折腾许久无果后无奈只好给element报了个 feature 。终于在此找到了思路: label slot
.
<div slot="label"> <svg-icon class="icons" :icon-class="iconClassName(route)" /> <span class="nav-title">{{route.name}}</span> </div> 复制代码
在 el-tab-pane
中间填上 slot
,我的icon们果然乖乖出现了! 开森!
sub-menu生成
因为用的 el-tab
做 navbar
,submenu生成将 router.children
放到 el-tab-pane之间即可
问题二:动态渲染active class
根据需求,点击submenu后颜色就要发生变化,正好应用一下动态绑定class:
<li v-for="(item, key, index) in route.children" :key="item.name" :id = "index" style="cursor: pointer;" :class="{'sub-active':activeIndex == item.path}" @click="activeIndex = item.path, clickLink(item, $event)"> {{item.name}} </li> 复制代码
根据path的唯一性,点击时 activeIndex
更改为当前的 path
,当前 submenu
会添加上 activeIndex
类.
问题三:点击submenu路由更改
导航的重要作用就是控制路有更改,应用 path.resolve
可以生成当前点击的路径。 li
中添加的 clickLink
方法为:
const path = this.resolvePath(routePath) this.$router.push(path) 复制代码
resolvePath
为:
resolvePath(routePath) { return path.resolve(this.basePath, routePath) } 复制代码
因为 this.$router.push
可以实现路由跳转,但是当前的跳转路径只解析出了子目录;
更正方案: 在 el-tab-pane
添加 :index="resolvePath(route.path)"
,在最初渲染时获取相应的父级path。 之后二级路由就变成了: http://localhost:9528/#/task/index
,嗯,是哀家想要的样子~
基本的功能以为就这样实现了,知道我手动输入了一下路径,,,
根据输入的path更新tab中对应项
active tab
由数据 activeName
控制; 子菜单 activeIndex
项绑定的是各自的 path
.
失败尝试一:
添加watch,监控router变化更改 activeName
以及 activeIndex
,未果;
失败尝试二:
应用 mixins
生成局部钩子函数,覆盖 activeName
以及 activeIndex
,未果;
失败原因: 应用路由钩子的思路是对的,但必须全局守卫,然后发现路由变化时更新 activeName
以及 activeIndex
对应的值,这时候再用 store
获取新值进行覆盖。
问题四:手动输入的路径渲染menu
- store中添加menu
const menu = { state: { menumain: '/', menusub:'overview' }, mutations: { updatemain (state,n) { state.menumain = n }, updatesub (state,n) { state.menusub = n } } } export default menu 复制代码
添加守卫函数:
router.beforeEach((to, from, next) => { // add menu change data let paths = to.path.trim().split('/') let activeName ='' let activeIndex ='' activeName = !!paths[2]==true ? '/'+ paths[1] : '/' store.commit('updatemain', activeName) activeIndex = !!paths[2]==true ? paths[2] : paths[1] store.commit('updatesub', activeIndex) //end menu }) 复制代码
navbar中更新数据:
computed: { newActiveName() { return this.$store.getters.menumain; }, newActiveSubMenu() { return this.$store.getters.menusub; } }, watch: { newActiveName(val){ this.activeName = val }, newActiveSubMenu(val) { this.activeIndex = val } } 复制代码
通过计算属性发现path更改并获取新值,然后watch监测到数据变化将新值赋给 activeName
以及 activeIndex
。
看下结果吧!
多说一句:burp是一款非常牛逼的安全产品,有需要的公司可以联系我洽谈试用。 目前,安全元素正在 招聘前端工程师,有意向的也可直接加我微信咨询。
忙到半夜总算实现了,开始以为很难,做的很慢,每次搞定一个小点又觉得很容易。还是“难者不会,会者不难”吧。
另:vue中很多设计都会有意想不到的用处,比如这次用到的插槽,动态绑定class;回想当年勇jq遍历li删掉active再给某一项添加active class的日子还历历在目。数据驱动解放dom操作,yeah~
以上所述就是小编给大家介绍的《应用el-tabs模拟nav menu组件》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 在 Angular 应用中创建包含组件
- React 中的高阶组件及其应用场景
- android获取应用四大组件列表以及详细信息
- 使用TypeScript开发React应用(二) - 创建组件
- 数据仓库组件:HBase 集群环境搭建和应用案例
- 使用Android架构组件开发MVVM模式的应用
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM程序设计培训教程
吴昊 / 中国铁道 / 2007-8 / 28.0
《ACM程序设计培训教程》不是这些专门问题的教科书,所以对这些问题所涉及知识的介绍不多,主要是分析一个个案例,介绍专属于ACM程序设计的方法和技巧。一起来看看 《ACM程序设计培训教程》 这本书的介绍吧!