美文网首页react & vue & angular
用 Vue 动画来实现登录/注册框的展示与折叠

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

作者: 茜Akane | 来源:发表于2023-01-15 23:45 被阅读0次

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

    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 来进行。

    相关文章

      网友评论

        本文标题:用 Vue 动画来实现登录/注册框的展示与折叠

        本文链接:https://www.haomeiwen.com/subject/dciicdtx.html