实现slideDown和slideUp可以用transition也可以用animation,本文用create-keyframe-animation动态实现。
1 <template> 2 <div> 3 <button @click="showDiv = !showDiv">测试</button> 4 <transition 5 v-on:enter="enter" 6 v-on:after-enter="afterEnter" 7 v-on:leave="leave" 8 v-on:after-leave="afterLeave" 9 > 10 <div :class="[showDiv ? 'is-show' : 'is-hide', 'pbox']" v-show="showDiv"> 11 <p>测试1</p> 12 <p>测试2</p> 13 <p>测试3</p> 14 <p>测试4</p> 15 <p>测试5</p> 16 </div> 17 </transition> 18 <div>ceshi</div> 19 </div> 20 </template> 21 <script> 22 import animations from "create-keyframe-animation"; 23 24 export default { 25 data() { 26 return { 27 showDiv: true, 28 animationName: "slideUp", 29 }; 30 }, 31 methods: { 32 animationGenerate(el, done, animationName, isReverse = false) { 33 // 定义动画内容 34 const animation = { 35 0: { 36 height: 0, 37 }, 38 100: { 39 height: `${el.scrollHeight}px`, 40 }, 41 }; 42 // 注册动画 43 animations.registerAnimation({ 44 name: animationName, // 动画名称 45 animation, // 动画 46 presets: { 47 // 预设项 48 duration: 200, // 持续时间 49 easing: "linear", // 时间函数 50 direction: isReverse ? "reverse" : "normal", 51 }, 52 }); 53 done 54 ? animations.runAnimation(el, animationName, done) 55 : animations.runAnimation(el, animationName); 56 }, 57 enter: function (el, done) { 58 this.animationGenerate(el, done, this.animationName); 59 }, 60 afterEnter(el) { 61 animations.unregisterAnimation(this.animationName); 62 // 这里用了scrollHeight 因为拿不到height和offsetHeight 63 el.style.cssText = `height: ${el.scrollHeight}px`; 64 }, 65 leave(el) { 66 this.animationGenerate(el, false, this.animationName, true); 67 }, 68 afterLeave(el) { 69 animations.unregisterAnimation(this.animationName); 70 el.style.cssText = `height: 0`; 71 } 72 } 73 }; 74 </script> 75 <style scoped> 76 .pbox { 77 overflow: hidden; 78 will-change: auto; 79 } 80 </style>
关键是未知块元素高度时候用什么获取,这里用scrollHeight。
后来发现有同学用了transition来实现的版本。比我这个简单。
https://www.cnblogs.com/moqiutao/p/10552736.html
主要注意的是:slideDown与slideUp都借助transition来实现只能在display部位none的情况下。如果display:none,transition将会失效。