这是在做项目时遇到的一个问题,在这里对其产生的原因、解决办法以及搜索资料获得的信息进行汇总与总结。
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;
}
}
...
}
效果
- 让 css 动画效果失效
- 登录和注册框会同时出现然后另一个消失,太过僵硬。
原因
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 来进行。
网友评论