App.js 5.2 KB

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