zoukankan      html  css  js  c++  java
  • 16.Vue技术栈开发实战-可收缩多级菜单的实现

    实现可收缩的侧边栏菜单。

    效果展示

    点击收缩的效果。如果只有一级菜单



    二级菜单

    多级菜单的情况

    展开的效果

    多级菜单

    开始

    我们之前封装的,我们的菜单要放在layout里

    我们最后封装的菜单组件,是要在sider里面

    sider-menu组件

    分别加sider-menu-submenu和side-menu-dropdown


    另外两个按钮 值在sideMenu里面用,所以这里就不导出去了。光导出sideMenu

    展开的时候用的iview的menu组件。
    收起来用的是dropDown组件

    它其实是一个个的按钮图标

    所以在我们的组件最外层肯定是有一个控制,默认是menu。dropDown放在下面的div里面。

    顶部需要一个logo



    所以顶部的log位置是允许自定义内容的,所以我们想到可以用slot插槽。在最上面用slot插槽。如果 还有其他的插槽 可以在底部也放一个slot

    展开是有状态的,我们在layout组件内是有这么个状态的。为true就是收缩。所以这个组件要把状态传进去。

    所以我们在layout里面

    调用组件,把属性:collapsed加进去。

    组件内定义collapsed属性。默认是展开的。

    menu展开的情况

    每一条menu-item就是一个菜单

    通过一个数组来渲染菜单。所以这个地方应该是用一个v-for去循环生成。我们如果在这里用v-for去循环的呢,只能循环出来一级

    如果我们的层级是很多级呢?而且层级的多少是不确定的呢

    我们之前讲过一个递归组件的形式,所以这里地方我们就要用到递归组件。

    在定义数据。用到iview里面的icon图标



    定义属性叫做list。把这个list传递进去。

    组件内定义属性 list

    默认如果是一个空数组,要在回调函数里面给它return 一个空的数组

    上面是简写的形式,补全的写法就是这种

    如果要返回一个空对象呢,不能直接写空对象,要用括号括起来。

    最终我们默认是这样的

    要递归组件,外层用template

    给没一个menu都加上一个name的属性

    用menu的name值来做key。这里判断item.children

    这个可以也要给组件menu-item

    menu-item上还需要一个nam的属性

    Submenu也需要name属性。



    最外层的div 宽度 要和父容器相等。

    所以设置div的宽度是100%

    菜单的宽度,来看下文档,它可以设置一个width值


    主题设置为dark,这样北京颜色都是黑色了

    有子菜单的情况

    因为我们的层级是未知的,所以这里需要用到递归组件。
    哪个部分是一直在循环下去的,就把谁拆出来 组装成一个组件。这里很显然,subMenu里面裹着menuItem。然后里面又有一个subMenu裹着menuItem。所以我们应该把subMenu拆出来,拆成递归组件。

    我们在side-menu-submenu里面封装。

    起个名字叫做ReSubMenu

    所以我们side-menu-submenu.vue改名叫做submenu

    side-menu-dropdown.vue也改名re-dropdown.vue

    应该把这整个对象传给递归组件。

    ReSubMenu引进来。

    这个地方就改成re-submenu

    组件定义了很多的条件和属性的话,可以分行显示、这样比较清晰一些。

    传入当前的item对象当做数据。对组组件内部来说,它就是当前的父级。

    递归组件内,定义parent属性。

    首先需要一个东西来作为插槽。显示当前这个submenu的title

    直接复制过来



    这样第一层就显示出来,

    接下来里面裹着的是menuItem

    menuItem应该使用v-for渲染children里面的数组了

    所以这里是个v-for

    在side-menu里面,在遍历的时候,是v-for循环一个template。在里面去判断当前item有没有children

    这块逻辑,在递归组件里面是复用的

    所以这里复制过来,逻辑应该是一样的

    ist改成parent.children

    递归组件,一定要给他一个name值。递归组件通过name值去调用他自身。


     
    subMenu需要一个name的属性。




    为了好看,把标题的name改的短一点





    side组件可以设置宽度。这里设置为300试一下

    递归组件内,只定义了title没有定义图标







    这里把所有的东西都包在了title里面

    单独的移除来

    这样 样式就对了

    再次强调递归组件的使用要领

    组件里面,每一块都是不断的在重复下去的。那你就应该把每一部分拆成一个组件。当递归组件使用。

    菜单收缩的功能

    这里这么窄,用menuItem肯定是不行的。

    先把上面的递归组件先注释掉。这里还是用template循环list

    没有children的情况下的效果图

    完成用Tooltip。里面裹着我们的a标签。

    for循环没个元素都要有key

    现在a标签都显示在一排了。

    所以需要给他一个样式。width是1000%,同时设置它为块级别的元素。

    这个地方受了ToolTip的影响

    为了不受tooltip的影响。加transfer属性
    a标签的外面裹了,ivu-tooltip


    把ivu-tooltip也设置成一个块级选择器。

    这样就换行了。

    图标显示的有点小。size设置为20

    图标呢,希望是白色



    tooltip的方向子设置在右边


     
    设置图标居中。这样图标就居中了。

    上下的padding,让图标之间有间隔

    默认的状态设置为收缩的状态

    子对象-dropdown递归组件封装

    定义属性parent,返回默认还是一个空对象。

    dropdown需要定义一个元素,是作为你鼠标触发显示的。把side-menu的a标签复制过去。



    把ReDropmdown引进来,然后使用这个组件。

    同样它也需要一个key,因为是v-for循环里面的

    传入parent属性

    报错

    这里加上v-if和v-else的判断



    DropdownMenu的 slot是list。里面用Template循环。



    加上name属性。

    这里的图标没有居中

    这里现在有菜单了

    把title显示出来



    显示在右边,右边开始的方向。

    接下来显示父界别的title,用span标签去显示。

    发现第一级也显示了title。我们希望的效果是菜单的第一级是不显示title的

    在里面显示title。而且这里看不到有问题,这是因为之前设置的文字颜色为白色导致的。

    这里把字体颜色白色去掉。不应该用css样式去写了 

    第一级的icon颜色设置为白色。

    icon-color设置为白色


    多级里面的颜色为

    递归组件内默认值就为灰色

    传入color为IconColor

    里面是对的,但是文字颜色不太对。文字颜色应该和图标的颜色是一样的

    因为我们是写在a那标签里面的,这里换成span标签。那么就不用再单独定义颜色了。

    这里也换成span标签,并且把class的类名改成drop-menu-span

    css里面也修改为drop-menu-span

    递归组件内也改

    我们应该是让第一级不显示title,让里面显示title

    也是和color一样,我们传入一个属性

    定义title的属性。默认是true,显示的

    第一级菜单我们不显示

    然后控制Title的显示

    这里也显示图标

    这里类型就是item.icon

    第一级的图标还是白色

    color属性改成这样

    具有字节别的菜单 居中的问题,所以居中的样式我们要改变一下。如果showTitle为true的话,说不它不是第一级

    不是第一级就偏左,否则的话就是居中

    现在是偏左的,但是的话 我们应该给他一个padding-left

    因为样式比较复杂,所以我们直接写在计算属性里

    return一个对象。



    然后是一级菜单居中的效果。这里不能设置它的宽度是100%了。因为给这个ivu-dropdown类型设置为100%后,那么后面你这些子菜单是根据父元素的ivu-dropdown的类名 的宽度来定义的。 那你后面的宽度都这么宽了。

    所以这里我们应该使用一个技巧。
    最外层的div给它一个类名



    给他设置为块级别元素,然后marin:0 auto;居中



    这样菜单就好看多了

    控制收缩和展开的状态

    把注释的代码都放开



    展开

    收缩

    v-if和v-show的对比

    都能实现对元素显示和隐藏的控制
    如果设置v-if为false。组件直接就不渲染了。
    v-show为false,只是设置css为display为none,里面的内容实际都是渲染出来了。
    所以当我们有时候会频繁的切换show或者hide的时候,我们应该使用v-show.这样就能减少我们性能的开销。

    所以这里我们要用v-show

    添加事件

    我们要知道,当前点击的是哪一项。

    把选中的name值打印一下




    收缩的状态下点击事件

    span绑定click事件,传入item.name



    dropdown绑定onclick事件





    点击这里,onclick事件触发了两次

    因为我们的组件嵌套了多次。触发了多个onclick事件

    只希望触发一次事件。如果当前不是第一级 输出。


    这样就只处罚一次事件了

    这里我们需要在这里抛出一个事件


    这样就没有问题了 点击事件


    以上就算是封装完成了。
     

    代码




     

    结束

  • 相关阅读:
    amazeui学习笔记--css(HTML元素1)--按钮Button
    【DataStructure】The description of Java Collections Framework
    android面试题 不仅仅是面试是一个很好的学习
    SVNclient安装与使用
    Microsoft Visual C++ Runtime Library Runtime Error解决的方式
    fullcalendar日历控件集合知识
    android存储阵列数据SharedPreferences
    Codeforces 484E Sign on Fence(是持久的段树+二分法)
    漂亮的表格样式(使用CSS样式表控制表格样式)
    交叉编译libxml2
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/13250387.html
Copyright © 2011-2022 走看看