index.vue 1.4 KB

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