vue+ts 折叠面板(封装transition)

336 阅读1分钟

最近开发一个项目需要自己实现一个折叠面板 在网上找到一个方法感觉还不错,但是忘记哪位大佬原创了,说声抱歉,这里记录一下,方便以后自己使用
先贴代码↓

// myTransition.vue
<script setup lang="ts">
const heightTransitionStyle = 'height .3s ease'

const hooks = {
  css: false,
  // 在元素被插入到 DOM 之前被调用
  // 用这个来设置元素的 "enter-from" 状态
  onBeforeEnter(el: any) {
    el.style.transition = heightTransitionStyle
    el.style.height = 0
  },

  // 在元素被插入到 DOM 之后的下一帧被调用
  // 用这个来开始进入动画
  onEnter(el: any, done: any) {
    // 调用回调函数 done 表示过渡结束
    // 如果与 CSS 结合使用,则这个回调是可选参数
    // 表示动画开始之后的样式,这里,可以设置小球完成动画之后的,结束状态
    el.style.height = `${el.scrollHeight}px`
    el.style.overflow = 'hidden'
  },

  // 当进入过渡完成时调用。
  onAfterEnter(el: any) {
    el.style.height = `${el.scrollHeight}px`
  },
  // 在 leave 钩子之前调用
  // 大多数时候,你应该只会用到 leave 钩子
  onBeforeLeave(el: any) {
    el.style.height = `${el.scrollHeight}px`
    el.style.overflow = 'hidden'
  },

  // 在离开过渡开始时调用
  // 用这个来开始离开动画
  onLeave(el: any, done: any) {
    // 调用回调函数 done 表示过渡结束
    // 如果与 CSS 结合使用,则这个回调是可选参数
    if (el.scrollHeight !== 0) {
      el.style.transition = heightTransitionStyle
      el.style.height = 0
    }
  },

  // 在离开过渡完成、
  // 且元素已从 DOM 中移除时调用
  onAfterLeave(el: any) {
    el.style.transition = ''
  },
}
</script>

<template>
  <transition v-bind="hooks">
    <slot />
  </transition>
</template>

针对原transition标签进行封装 设置合适自己的动画后直接使用即可
注: MyTransition标签内的内容需要设置 v-show属性

例:

<MyTransition>
  <div v-show="show" class="content">
    <div class="p-[0_10px_10px] md:p-[0_20px_36px] text-[14px] md:text-[18px] text-[#46465c]">
      <div v-if="data.content" v-html="data.content" />
      <slot :name="data.slotName" />
    </div>
  </div>
</MyTransition>

而后只需改变show的属性即可完成折叠面板效果
如需手风琴效果,只需额外使用一个字段记录选中状态即可
例:

image.png