You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
4.7 KiB

4 weeks ago
  1. import Vue from 'vue'
  2. import {
  3. getMatchedComponentsInstances,
  4. getChildrenComponentInstancesUsingFetch,
  5. promisify,
  6. globalHandleError,
  7. sanitizeComponent
  8. } from './utils'
  9. import NuxtLoading from './components/nuxt-loading.vue'
  10. import NuxtBuildIndicator from './components/nuxt-build-indicator'
  11. import _6f6c098b from '..\\layouts\\default.vue'
  12. import _2d297eb3 from '..\\layouts\\sign.vue'
  13. const layouts = { "_default": sanitizeComponent(_6f6c098b),"_sign": sanitizeComponent(_2d297eb3) }
  14. export default {
  15. render (h, props) {
  16. const loadingEl = h('NuxtLoading', { ref: 'loading' })
  17. const layoutEl = h(this.layout || 'nuxt')
  18. const templateEl = h('div', {
  19. domProps: {
  20. id: '__layout'
  21. },
  22. key: this.layoutName
  23. }, [layoutEl])
  24. const transitionEl = h('transition', {
  25. props: {
  26. name: 'layout',
  27. mode: 'out-in'
  28. },
  29. on: {
  30. beforeEnter (el) {
  31. // Ensure to trigger scroll event after calling scrollBehavior
  32. window.$nuxt.$nextTick(() => {
  33. window.$nuxt.$emit('triggerScroll')
  34. })
  35. }
  36. }
  37. }, [templateEl])
  38. return h('div', {
  39. domProps: {
  40. id: '__nuxt'
  41. }
  42. }, [
  43. loadingEl,
  44. h(NuxtBuildIndicator),
  45. transitionEl
  46. ])
  47. },
  48. data: () => ({
  49. isOnline: true,
  50. layout: null,
  51. layoutName: '',
  52. nbFetching: 0
  53. }),
  54. beforeCreate () {
  55. Vue.util.defineReactive(this, 'nuxt', this.$options.nuxt)
  56. },
  57. created () {
  58. // Add this.$nuxt in child instances
  59. Vue.prototype.$nuxt = this
  60. // add to window so we can listen when ready
  61. if (process.client) {
  62. window.$nuxt = this
  63. this.refreshOnlineStatus()
  64. // Setup the listeners
  65. window.addEventListener('online', this.refreshOnlineStatus)
  66. window.addEventListener('offline', this.refreshOnlineStatus)
  67. }
  68. // Add $nuxt.error()
  69. this.error = this.nuxt.error
  70. // Add $nuxt.context
  71. this.context = this.$options.context
  72. },
  73. mounted () {
  74. this.$loading = this.$refs.loading
  75. },
  76. watch: {
  77. 'nuxt.err': 'errorChanged'
  78. },
  79. computed: {
  80. isOffline () {
  81. return !this.isOnline
  82. },
  83. isFetching() {
  84. return this.nbFetching > 0
  85. }
  86. },
  87. methods: {
  88. refreshOnlineStatus () {
  89. if (process.client) {
  90. if (typeof window.navigator.onLine === 'undefined') {
  91. // If the browser doesn't support connection status reports
  92. // assume that we are online because most apps' only react
  93. // when they now that the connection has been interrupted
  94. this.isOnline = true
  95. } else {
  96. this.isOnline = window.navigator.onLine
  97. }
  98. }
  99. },
  100. async refresh () {
  101. const pages = getMatchedComponentsInstances(this.$route)
  102. if (!pages.length) {
  103. return
  104. }
  105. this.$loading.start()
  106. const promises = pages.map((page) => {
  107. const p = []
  108. // Old fetch
  109. if (page.$options.fetch && page.$options.fetch.length) {
  110. p.push(promisify(page.$options.fetch, this.context))
  111. }
  112. if (page.$fetch) {
  113. p.push(page.$fetch())
  114. } else {
  115. // Get all component instance to call $fetch
  116. for (const component of getChildrenComponentInstancesUsingFetch(page.$vnode.componentInstance)) {
  117. p.push(component.$fetch())
  118. }
  119. }
  120. if (page.$options.asyncData) {
  121. p.push(
  122. promisify(page.$options.asyncData, this.context)
  123. .then((newData) => {
  124. for (const key in newData) {
  125. Vue.set(page.$data, key, newData[key])
  126. }
  127. })
  128. )
  129. }
  130. return Promise.all(p)
  131. })
  132. try {
  133. await Promise.all(promises)
  134. } catch (error) {
  135. this.$loading.fail(error)
  136. globalHandleError(error)
  137. this.error(error)
  138. }
  139. this.$loading.finish()
  140. },
  141. errorChanged () {
  142. if (this.nuxt.err && this.$loading) {
  143. if (this.$loading.fail) {
  144. this.$loading.fail(this.nuxt.err)
  145. }
  146. if (this.$loading.finish) {
  147. this.$loading.finish()
  148. }
  149. }
  150. },
  151. setLayout (layout) {
  152. if(layout && typeof layout !== 'string') {
  153. throw new Error('[nuxt] Avoid using non-string value as layout property.')
  154. }
  155. if (!layout || !layouts['_' + layout]) {
  156. layout = 'default'
  157. }
  158. this.layoutName = layout
  159. this.layout = layouts['_' + layout]
  160. return this.layout
  161. },
  162. loadLayout (layout) {
  163. if (!layout || !layouts['_' + layout]) {
  164. layout = 'default'
  165. }
  166. return Promise.resolve(layouts['_' + layout])
  167. }
  168. },
  169. components: {
  170. NuxtLoading
  171. }
  172. }