博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue组件之menu导航菜单
阅读量:5771 次
发布时间:2019-06-18

本文共 4803 字,大约阅读时间需要 16 分钟。

组件之间的通信

for Mac
for Windows
快速入门
进阶配置
多语言支持
复制代码

selected的传递

如图所示,关于(selected:被选中的那个item),在menu里面控制,通过watchChild“监听每个item”,一旦menu-item被点击便会触发

this.$emit('menuItemUpdate',this.name)复制代码

这里menu便会通过menu-item$emit$on实现数据的传递

watchChild(){                this.items.forEach(vm=>{                    vm.$on('menuItemUpdate',name=>{                        this.$emit('update:selected',[name])                    })                })            },复制代码

这里的this.items就是收集的每一个menu-item,这在一开始就已经完成了。 要用到依赖注入,这里面子组件menu-item都直接操作menudata,耦合度非常高。

//menu provide(){          return {              root:this          }        }复制代码
//menu-item inject:['root'],        created(){           this.root.addItem(this)          //.........        },复制代码

然后告诉menu-item你可以被选中了。updated钩子函数用作完成这个任务再适合不过了

updated(){           this.updateChild()        }, methods:{     updateChild(){              this.items.forEach(vm=>{                  if(this.selected.indexOf(vm.name)>-1){                      vm.selected = true                  }else{                      vm.selected = false                  }              })          } }        复制代码

路径元素的收集

menu-item被选中时,触发tellParents函数,收集这条路径上所有父元素的name,把这个收集好的数据放到selectedArr里面。这个还可以用来高亮路径上的父元素。 在click的时候触发onClick函数

onClick(){                //...........                let subFather = this.$parent.$el.classList.contains('x-sub-menu') this.$parent.$el.classList.contains('x-sub-menu')                let groupFather = this.$parent.$el.classList.contains('x-menu-item-group')               //..........                if(subFather||groupFather){                 //.......                    this.tellParents(this)                   //.......                }else{                    //.......                }            },复制代码

tellParents递归调用自身来收集 name

tellParents(that){                if(that.$parent.$parent.$options.name==='x-sub-menu' ||that.$parent.$parent.$options.name==='x-menu-item-group'){                    this.root.selectedArr.unshift(that.$parent.name)                    this.tellParents(that.$parent)                }else{                    this.root.selectedArr.unshift(that.$parent.name)                    console.log(this.root.selectedArr)                }            },复制代码

最后就是我希望在menu-item被选中后,可以关闭路径的所有弹出框popover。 这同样需要一个递归遍历

childClosePopover(){                if(this.$parent.$options.name==='x-sub-menu'){                    this.open = false                    this.$parent.childClosePopover()                }            },复制代码

自定义主题颜色的实现

参照了一下Menu Attribute。 这里的文字颜色和图标颜色是同步的, hover的css效果和active的一样

  • text-color文字颜色 。
  • active-color被选中颜色。
  • back-ground-color正常背景色 。
  • active-back-ground-color被选中的背景色 。

数据传递

如图所示的紫色的路线,通过递归遍历通知menu树里面的每一个分支,改变颜色,是否垂直,disabled等等。 大部分添加的功能都在这条线上实现通信。

js控制颜色的更改

watch:{            selected(){                if(this.selected&&........{                    this.$refs.item.style.backgroundColor = ........                    this.$refs.item.style.color = .........                    //...........                }else{                  //............                }            }        }复制代码

弹出框的问题

element对弹出框的操作是以在body上添加子节点的方式。这样子最直接的就是避免了可能存在overflow:hideen的问题。 后面的定位只需要用js来完成就行了,还要考虑到scroll的问题。

最麻烦的地方在于动画过渡上,单纯的用css会有弹出框回到原点的问题。 这里就需要用到 。 官网在这上面的说的很明确,但是实现过程中也踩了一些坑

  • 动画瞬间完成的问题,这在官网上的解释时只用JavaScript做过渡的时候(没用css)的情况下动画会瞬间完成,要使用done。之后试了并没有用。这里并不是只用JavaScript做过渡的。之后想了一下,既然beforeEnterenter瞬间就执行了,并没有动画的事件间隔,为什么不自己加一个 settimeout呢,问题就解决了,可能这种解决方法并不是很好。这里不用$nextTick
enter(el) {    setTimeout(()=>{      //.....      })    },复制代码
  • 钩子中设置的一些额外的css属性要在afterEnter改回来啊,其中就例如overflow:hiddenheight,导致在vertical垂直面板上弹出框不会撑开父元素的问题。
afterLeave(el){              el.style.overflow = ''              if(this.vertical){                  el.style.height=''              }          },复制代码

后面就是和定位弹出框一样类似的js操作,在menu导航菜单里面我并没有这么做,后面会改成这样的吧。

beforeEnter(el) {                el.style.position= 'absolute'                el.style.transform=.......                //.........          },     enter(el) {             //......          },复制代码

处理一些细枝末节的问题

  • hover触发和click触发
  • 弹出框移出消失的时间控制和动画抖动。
  • 高亮线条只在一级子组件中存在
  • menu-item-group组件的添加,其实只是作为一个中转站而已,无非是拷贝一些函数。
  • 一些多层嵌套的位置问题,尚未完成。

遇到的一些css问题

  • 横版里面active下面的亮条显示,一开始就是设置menu-item里面的border-bottom,因为同时设置了transition。在显示的时候会有高度抖动的问题。后来改用伪类完成,不过在自定义颜色的时候非常麻烦。这个方法也放弃了。最后只有在下面加一个div代替border-bottom作为高亮线条,方法虽然很蠢,但是有效。
  • scoped里面给某些子组件添加css样式用到了 /deep/深度作用。

简单的总结?

其实以这种显而易见的数据流作为基础,多增加一些功能无非是函数的添加和css的修改。找bug和维护也是相对比较轻松的。最后您如果觉得还不错的话,给我的项目一个star想必也是极好的。

转载于:https://juejin.im/post/5c937bb0f265da60ce37a3a4

你可能感兴趣的文章
Bug2算法的实现(RobotBASIC环境中仿真)
查看>>
忘记root密码修改方法
查看>>
OGRE教程SceneNode, Entity, SceneManager and Get start 的讲解
查看>>
类的实现和测试(课上作业)
查看>>
《程序员面试宝典》读书笔记
查看>>
office 2016文件已损坏,无法打开
查看>>
Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)(A.暴力,B.优先队列,C.dp乱搞)...
查看>>
Codeforces Round #411 (Div. 2)(A,B,C,D 四水题)
查看>>
Spring Boot快速入门(四):使用jpa进行数据库操作
查看>>
判断点是否在多边形内(包括在多边形上)
查看>>
UIEvent
查看>>
两个以上gameobject同时调用同一函数时候transform代码中改变但是实际效果并不改变的诡异问题...
查看>>
类和对象
查看>>
网页链接qq
查看>>
java----spring框架
查看>>
框架流程
查看>>
Dot NET 内存泄漏
查看>>
c#关于时间TimeHelper类的总结
查看>>
Web APi入门之移除XML格式(一)
查看>>
SDK:用GetWindowRect GetClientRect 获得控件在客户区的RECT
查看>>