用 Vue 动画来实现登录/注册框的展示与折叠

这是在做项目时遇到的一个问题,在这里对其产生的原因、解决办法以及搜索资料获得的信息进行汇总与总结。

1.需求

想通过改变上下两个div的高度来实现登录/注册框的展示与折叠。

2. 用 v-show 实现

            <transition name="slide">
              <div v-bind:class="{ show: isShowRegister }" class="register">
                <input type="text" v-model="register.username" placeholder="用户名">
                <input type="password" v-model="register.password" @keyup.enter="onRegister" placeholder="密码">
                <p v-bind:class="{ error: register.isError }"> {{ register.notice }}</p>
                <div class="button" @click="onRegister">创建账号</div>
              </div>
            </transition>
            <h3 @click="showLogin">登录</h3>
            <transition name="slide">
              <div v-bind:class="{ show: isShowLogin }" class="login">
                <input type="text" v-model="login.username" placeholder="输入用户名">
                <input type="password" v-model="login.password" @keyup.enter="onLogin" placeholder="密码">
                <p v-bind:class="{ error: login.isError }"> {{ login.notice }}</p>
                <div class="button" @click="onLogin"> 登录</div>
              </div>
            </transition>

CSS部分

    .login, .register {
        padding: 0px 20px;
        border-top: 1px solid #eee;
        // height: 0;
        overflow: hidden;
        transition: height .4s;

        .slide-enter-active {
            animation: slide-in .5s;
        }

        .slide-leave-active {
            animation: slide-in .5s reverse;
        }

        @keyframes slide-in {
            0% {
                height: 0px;
            }
            100% {
                height: 200px;
            }
        }
      ...
      }

效果

  1. 让 css 动画效果失效
  2. 登录和注册框会同时出现然后另一个消失,太过僵硬。

原因
v-show的本质是利用布尔值来操控 display:none;display:block; 的,display的值改变会引起HTML画布的重绘,所以是不会有动画效果的。

3. 通过改变 height 来实现

由于登录与注册框需要来回切换,所以将 v-show 改成绑定的一个 class ,通过标志位来切换显示哪一个。

<div v-bind:class="{ show: isShowRegister }" class="register">
<div v-bind:class="{ show: isShowLogin }" class="login">

将登录与注册框的高度都设置为0,通过 class="show" 来进行切换。

    .login,
    .register {
      padding: 0px 20px;
      border-top: 1px solid #eee;
      height: 0;
      overflow: hidden;
      transition: height .4s;

      &.show {
        height: 193px;
      }
      ...
      }

效果
能够较为丝滑的展开、折叠登录与注册框。

4. 参考与扩展

在搜索过程中主要参考了以下博客:
Vue | 显示切换(v-if与v-show,display,visibility与opacity)_MGsniper的博客
&符号该怎么用?_Milk595的博客-CSDN博客
在看博客的同时明白了一些知识点,在这里做些笔记。

4.1 显示切换(v-if与v-show,display,visibility与opacity)

  • v-show:实际就是根据绑定的布尔数据,对元素进行动态添加或取消“display:none”进行显示切换的。
    当节点的属性为display:none时,其自身与后代节点不再生成盒模型以占位,但html节点并没有真的被删除。
    当祖先节点为display:none时,后代节点均受影响,且重写子节点display属性无效。
  • v-if:与v-show不同的是,v-if是根据条件渲染元素,一旦不满足条件,元素则会直接被删除。
  • 动态绑定visibility,通过修改“visibility”属性实现显示切换。
    visibility:visibility属性不影响元素占位。hidden可让元素生成不可见盒,元素虽不可见,但仍生成盒模型,保持占位,布局不塌陷。
    子元素默认继承父元素visibility属性,但子元素若重写属性,则不受父级影响。
  • opacity属性仅改变元素的透明度,不影响元素的占位。
    opacity属性不可继承,但祖先元素的opacity会影响后代。后代元素的opacity取最小值显示。若祖先元素opacity为0,后代为1,则0生效。若祖先为1,后代为0.5,则0.5生效。
    opacity属性不影响事件触发。

4.2 & 符号

这是less、sass语法,& 表示嵌套的上一级选择器。

.border {
    &.top{
    margin: 5px;
        }
    }
    .color{
    border-color: green;
        }
    }
}

.border.top 是串联选择器,作用在同一标签。
.border .color 是后代选择器,作用在不同标签上。

4.3 实现display:block“过渡动画”

vue 数字动画递增_一行代码实现display"过渡动画"原理_weixin_39707478的博客-CSDN博客
大致是通过访问特殊api来清空队列,让 display:block; 快速渲染,然后动画就可以根据 block 来进行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容