vShow.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import type { ObjectDirective } from '@vue/runtime-core'
  2. export const vShowOriginalDisplay: unique symbol = Symbol('_vod')
  3. export const vShowHidden: unique symbol = Symbol('_vsh')
  4. export interface VShowElement extends HTMLElement {
  5. // _vod = vue original display
  6. [vShowOriginalDisplay]?: string
  7. [vShowHidden]?: boolean
  8. }
  9. export const vShow: ObjectDirective<VShowElement> & { name?: 'show' } = {
  10. beforeMount(el, { value }, { transition }) {
  11. el[vShowOriginalDisplay] =
  12. el.style.display === 'none' ? '' : el.style.display
  13. if (transition && value) {
  14. transition.beforeEnter(el)
  15. } else {
  16. setDisplay(el, value)
  17. }
  18. },
  19. mounted(el, { value }, { transition }) {
  20. if (transition && value) {
  21. transition.enter(el)
  22. }
  23. },
  24. updated(el, { value, oldValue }, { transition }) {
  25. if (!value === !oldValue) return
  26. if (transition) {
  27. if (value) {
  28. transition.beforeEnter(el)
  29. setDisplay(el, true)
  30. transition.enter(el)
  31. } else {
  32. transition.leave(el, () => {
  33. setDisplay(el, false)
  34. })
  35. }
  36. } else {
  37. setDisplay(el, value)
  38. }
  39. },
  40. beforeUnmount(el, { value }) {
  41. setDisplay(el, value)
  42. },
  43. }
  44. if (__DEV__) {
  45. vShow.name = 'show'
  46. }
  47. function setDisplay(el: VShowElement, value: unknown): void {
  48. el.style.display = value ? el[vShowOriginalDisplay]! : 'none'
  49. el[vShowHidden] = !value
  50. }
  51. // SSR vnode transforms, only used when user includes client-oriented render
  52. // function in SSR
  53. export function initVShowForSSR(): void {
  54. vShow.getSSRProps = ({ value }) => {
  55. if (!value) {
  56. return { style: { display: 'none' } }
  57. }
  58. }
  59. }