nuxt-child.js 3.0 KB

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