App.js 5.1 KB

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