zoukankan      html  css  js  c++  java
  • Vue中实现菜单下拉、收起的动画效果

    菜单的下拉和收起动画,看起来好像比较简单,但是搞了半天。

    最后可以使用的代码:

            <transition
              name="default"
              v-on:enter="menuEnter"
              v-on:leave="menuLeave"
              enter-class="default-enter"
              leave-to-class="default-leave-to"
            >
              <ul v-if="hasChildren(node, index)" class="menu-l2">
                <li
                  v-for="(subnode, subIndex) in node.children"
                  :key="subnode.id"
                  @click.prevent="handleChildNodeClick(subnode, subIndex)"
                  class="node-l2"
                  :class="{ 'node-l2-active' : (subIndex == activeChildNodeIndex)}"
                >{{ subnode.name }}</li>
              </ul>
            </transition>
    

    js,这里是vue中的methods部分

        menuEnter: function(el, done) {
        //这行是关键
          el.offsetWidth;
          el.style.maxHeight =  this.nodes[this.activeParentNodeIndex].children.length * 4 + "rem";
          el.style.transition = "all 0.3s ease-in";
          done();
        },
        menuLeave: function(el) {
          el.offsetWidth;
          el.style.maxHeight = 0;
          el.style.transition = "all 0.3s ease-out";
        }
    

    css:

    //transitions
    .default-enter-active {
        transition: all 0.3s ease-in;
    }
    
    .default-leave-active {
        transition: all 0.3s ease-out;
    }
    
    .default-enter,
    .default-leave-to {
        max-height: 0;
    }
    

    说明

    这里结合了js和css,其实只用js也可以,但是稍微麻烦。

    只用css也可以,但是效果会稍微差一些(后面会解释)。


    这里实现下拉和收起,利用的css的transition
    vue中定义了三个状态,对应显示,分别是(事件/css类)

    • before-enter/v-enter:动画开始/初始状态
    • enter/v-enter-active:动画过程/中间状态
    • after-enter/v-enter-to:动画结束/结束状态

    对于隐藏(leave)也同样

    计算过度高度

    这里对于显示,利用的是max-height属性,第一个关键点在于,初始状态max-height设置为0,在中间状态设置为下拉框的实际大小。这样才会出现高度变化的下拉效果。

    这也就是为什么使用js hook,而不是直接使用css的原因呢,因为子菜单高度无法确切知道,如果对效果不敏感,可以直接指定一个较大的max-height,但是为了效果好,还是根据菜单长度确定过度最好。

    控制页面刷新

    第二个关键点在于 el.offsetWidth;这一句看似无用的代码,不加的话,浏览器不会有动画效果,加上以后,按照网上的说法,会强制触发绘制。

    其实在vue的官方文档有提到

    When using JavaScript-only transitions, the done callbacks are required for the enter and leave hooks. Otherwise, the hooks will be called synchronously and the transition will finish immediately.

    但是我测试了一下,调用done()还是没有效果,不清楚原因。

  • 相关阅读:
    五、K3 WISE 开发插件《直接SQL报表开发新手指导
    四、K3 WISE 开发插件《工业单据老单插件开发新手指导》
    三、K3 WISE 开发插件《K3 WISE开发手册》
    二、K3 WISE 开发插件《 工业单据老单客户端插件事件、属性、方法》
    一、K3 WISE 开发插件《K3 WISE常用数据表整理》
    首次安装金蝶注意事项
    金蝶系统,反写采购价格管理资料状态怎么选择?
    网络编程----socket套接字的黏包问题
    网络编程----socket套接字
    网络编程----网络协议篇(osi七层协议)
  • 原文地址:https://www.cnblogs.com/mosakashaka/p/12609236.html
Copyright © 2011-2022 走看看