vue.js - 无论如何在过渡结束时保持显示块?
问题描述
我正在尝试实现不应该影响另一个元素在目标元素附近的位置的惊人动画。过渡没问题,但问题是当它完成动画时,它display: none;
默认设置属性,这使得下一个元素跳起来填充它的位置。
我想知道我是否可以保留它display: block;
并仅依赖它,opacity
但我无法从文档中获得任何线索。是否可以?还是应该改用动画库?
为了演示,请运行此代码段
console.clear();
new Vue({
el: '#app',
data() {
return {
showItems: false,
}
},
mounted() {
this.$nextTick(() => {
this.showItems = true
});
}
});
.slide-in-enter-active {
transition: opacity .5s linear, transform .5s cubic-bezier(.2, .5, .1, 1);
transition-delay: calc( 0.1s * var(--i));
}
.slide-in-leave-active {
transition: opacity .4s linear, transform .4s cubic-bezier(.5, 0, .7, .4); //cubic-bezier(.7,0,.7,1);
transition-delay: calc( 0.1s * (var(--total) - var(--i)));
}
.slide-in-enter,
.slide-in-leave-to {
opacity: 0;
}
.slide-in-enter,
.slide-in-leave-to {
transform: translateX(1rem);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="showItems = !showItems">Show/Hide Items</button>
<!--
in real world, this would be dynamic,
which is the height is unknown (like larger text on a larger screen).
-->
<transition-group tag="ul" name="slide-in" :style="{ '--total': 10 }">
<li v-for="i in 10" :key="i" :style="{'--i': i}" v-show="showItems">
Item {{ i }}
</li>
</transition-group>
<div class="the-content-that-should-not-moved-up">
<p style="margin:0;">Another content that should not moved up</p>
<p style="margin:0;">Another content that should not moved up</p>
<p style="margin:0;">Another content that should not moved up</p>
<p style="margin:0;">Another content that should not moved up</p>
</div>
</div>
解决方案
您可以在隐藏列表时保存列表的当前高度,然后应用样式绑定以相应地设置其高度:
在元素 (a ) 上应用模板引用,以便我们稍后可以获取元素的高度。
transition-group
ul
<transition-group ref="list">
添加一个
listHeight
数据属性来存储transition-group
的高度:data() { return { listHeight: null } }
将样式绑定添加到
transition-group
要设置的元素height
:<transition-group :style="{ height: listHeight && `${listHeight}px` }">
添加一个观察者,仅在隐藏时
showItems
捕获高度:transition-group
watch: { showItems(showItems) { if (showItems) { this.listHeight = null } else { this.listHeight = this.$refs.list.$el.offsetHeight } } }
console.clear();
new Vue({
el: '#app',
data() {
return {
showItems: false,
listHeight: null,
}
},
mounted() {
this.$nextTick(() => {
this.showItems = true
});
},
watch: {
showItems(showItems) {
if (showItems) {
this.listHeight = null
} else {
this.listHeight = this.$refs.list.$el.offsetHeight
}
}
}
});
.slide-in-enter-active {
transition: opacity .5s linear, transform .5s cubic-bezier(.2, .5, .1, 1);
transition-delay: calc( 0.1s * var(--i));
}
.slide-in-leave-active {
transition: opacity .4s linear, transform .4s cubic-bezier(.5, 0, .7, .4); //cubic-bezier(.7,0,.7,1);
transition-delay: calc( 0.1s * (var(--total) - var(--i)));
}
.slide-in-enter,
.slide-in-leave-to {
opacity: 0;
}
.slide-in-enter,
.slide-in-leave-to {
transform: translateX(1rem);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="showItems = !showItems">Show/Hide Items</button>
<!--
in real world, this would be dynamic,
which is the height is unknown (like larger text on a larger screen).
-->
<transition-group tag="ul" name="slide-in" :style="{ '--total': 10, height: listHeight && `${listHeight}px` }" ref="list">
<li v-for="i in 10" :key="i" :style="{'--i': i}" v-show="showItems">
Item {{ i }}
</li>
</transition-group>
<div class="the-content-that-should-not-moved-up">
<p style="margin:0;">Another content that should not moved up</p>
<p style="margin:0;">Another content that should not moved up</p>
<p style="margin:0;">Another content that should not moved up</p>
<p style="margin:0;">Another content that should not moved up</p>
</div>
</div>
推荐阅读
- vba - 如何使用我拥有的自定义代码将小数转换为分数?
- json - 如何使用响应数据解码值
- python - 修复检查单词是否出现相邻的 2 个字符的程序
- git - 如何在本地拉出远程分支?
- java - 反正有一个 for 循环在后台运行,另一个任务在前面吗?
- ruby - 如何使用 Unix 套接字对通信 Rust 和 Ruby 进程
- redirect - 我如何重定向到第一个子组件 vue 路由器
- reactjs - 如何在 React/JSX 中使用 Eventbrite 的嵌入式小部件?
- html - 双宽非比例字体
- c# - 能够使用多个 po 文件进行本地化 asp.net core 2.2