index.vue 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <template>
  2. <div ref="contentRef" class="ui-size-animation" :class="{ ready, show: max !== 0, [animationStyle]: animationStyle }" :style="origin && { 'max-height': max + 'px' }">
  3. <slot />
  4. </div>
  5. </template>
  6. <script lang="ts" setup>
  7. import { defineExpose, defineProps, ref, watchEffect } from 'vue'
  8. import { changeWHFactory } from '@kankan/utils'
  9. defineOptions({
  10. name: 'UISizeAnimation',
  11. })
  12. const props = defineProps({
  13. attr: {
  14. type: String,
  15. default: 'height',
  16. },
  17. animationStyle: {
  18. type: String,
  19. default: 'height',
  20. },
  21. })
  22. const [contentRef, changeShow, max, origin, show, ready, refer] = changeWHFactory(false, props.attr)
  23. const animation = ref(false)
  24. watchEffect(() => {
  25. const dom = contentRef.value
  26. if (dom) {
  27. const startHandler = () => (animation.value = true)
  28. const endHandler = () => (animation.value = false)
  29. dom.addEventListener('transitionstart', startHandler)
  30. dom.addEventListener('transitionend', endHandler)
  31. return () => {
  32. dom.removeEventListener('transitionstart', startHandler)
  33. dom.removeEventListener('transitionend', endHandler)
  34. }
  35. }
  36. })
  37. defineExpose({
  38. changeShow: (setShow, ...args) => {
  39. if (show !== setShow) {
  40. animation.value = true
  41. }
  42. return changeShow(setShow, ...args)
  43. },
  44. show,
  45. animation,
  46. ready,
  47. refer,
  48. })
  49. </script>
  50. <!-- <script>
  51. export default { name: 'UiSizeAnimation' }
  52. </script> -->