nuxt-child.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. export default {
  2. name: 'NuxtChild',
  3. functional: true,
  4. props: {
  5. nuxtChildKey: {
  6. type: String,
  7. default: ''
  8. },
  9. keepAlive: Boolean,
  10. keepAliveProps: {
  11. type: Object,
  12. default: undefined
  13. }
  14. },
  15. render (_, { parent, data, props }) {
  16. const h = parent.$createElement
  17. data.nuxtChild = true
  18. const _parent = parent
  19. const transitions = parent.$nuxt.nuxt.transitions
  20. const defaultTransition = parent.$nuxt.nuxt.defaultTransition
  21. let depth = 0
  22. while (parent) {
  23. if (parent.$vnode && parent.$vnode.data.nuxtChild) {
  24. depth++
  25. }
  26. parent = parent.$parent
  27. }
  28. data.nuxtChildDepth = depth
  29. const transition = transitions[depth] || defaultTransition
  30. const transitionProps = {}
  31. transitionsKeys.forEach((key) => {
  32. if (typeof transition[key] !== 'undefined') {
  33. transitionProps[key] = transition[key]
  34. }
  35. })
  36. const listeners = {}
  37. listenersKeys.forEach((key) => {
  38. if (typeof transition[key] === 'function') {
  39. listeners[key] = transition[key].bind(_parent)
  40. }
  41. })
  42. if (process.client) {
  43. // Add triggerScroll event on beforeEnter (fix #1376)
  44. const beforeEnter = listeners.beforeEnter
  45. listeners.beforeEnter = (el) => {
  46. // Ensure to trigger scroll event after calling scrollBehavior
  47. window.$nuxt.$nextTick(() => {
  48. window.$nuxt.$emit('triggerScroll')
  49. })
  50. if (beforeEnter) {
  51. return beforeEnter.call(_parent, el)
  52. }
  53. }
  54. }
  55. // make sure that leave is called asynchronous (fix #5703)
  56. if (transition.css === false) {
  57. const leave = listeners.leave
  58. // only add leave listener when user didnt provide one
  59. // or when it misses the done argument
  60. if (!leave || leave.length < 2) {
  61. listeners.leave = (el, done) => {
  62. if (leave) {
  63. leave.call(_parent, el)
  64. }
  65. _parent.$nextTick(done)
  66. }
  67. }
  68. }
  69. let routerView = h('routerView', data)
  70. if (props.keepAlive) {
  71. routerView = h('keep-alive', { props: props.keepAliveProps }, [routerView])
  72. }
  73. return h('transition', {
  74. props: transitionProps,
  75. on: listeners
  76. }, [routerView])
  77. }
  78. }
  79. const transitionsKeys = [
  80. 'name',
  81. 'mode',
  82. 'appear',
  83. 'css',
  84. 'type',
  85. 'duration',
  86. 'enterClass',
  87. 'leaveClass',
  88. 'appearClass',
  89. 'enterActiveClass',
  90. 'enterActiveClass',
  91. 'leaveActiveClass',
  92. 'appearActiveClass',
  93. 'enterToClass',
  94. 'leaveToClass',
  95. 'appearToClass'
  96. ]
  97. const listenersKeys = [
  98. 'beforeEnter',
  99. 'enter',
  100. 'afterEnter',
  101. 'enterCancelled',
  102. 'beforeLeave',
  103. 'leave',
  104. 'afterLeave',
  105. 'leaveCancelled',
  106. 'beforeAppear',
  107. 'appear',
  108. 'afterAppear',
  109. 'appearCancelled'
  110. ]