nuxt.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import Vue from 'vue'
  2. import { compile } from '../utils'
  3. import NuxtError from './nuxt-error.vue'
  4. import NuxtChild from './nuxt-child'
  5. export default {
  6. name: 'Nuxt',
  7. components: {
  8. NuxtChild,
  9. NuxtError
  10. },
  11. props: {
  12. nuxtChildKey: {
  13. type: String,
  14. default: undefined
  15. },
  16. keepAlive: Boolean,
  17. keepAliveProps: {
  18. type: Object,
  19. default: undefined
  20. },
  21. name: {
  22. type: String,
  23. default: 'default'
  24. }
  25. },
  26. errorCaptured (error) {
  27. // if we receive and error while showing the NuxtError component
  28. // capture the error and force an immediate update so we re-render
  29. // without the NuxtError component
  30. if (this.displayingNuxtError) {
  31. this.errorFromNuxtError = error
  32. this.$forceUpdate()
  33. }
  34. },
  35. computed: {
  36. routerViewKey () {
  37. // If nuxtChildKey prop is given or current route has children
  38. if (typeof this.nuxtChildKey !== 'undefined' || this.$route.matched.length > 1) {
  39. return this.nuxtChildKey || compile(this.$route.matched[0].path)(this.$route.params)
  40. }
  41. const [matchedRoute] = this.$route.matched
  42. if (!matchedRoute) {
  43. return this.$route.path
  44. }
  45. const Component = matchedRoute.components.default
  46. if (Component && Component.options) {
  47. const { options } = Component
  48. if (options.key) {
  49. return (typeof options.key === 'function' ? options.key(this.$route) : options.key)
  50. }
  51. }
  52. const strict = /\/$/.test(matchedRoute.path)
  53. return strict ? this.$route.path : this.$route.path.replace(/\/$/, '')
  54. }
  55. },
  56. beforeCreate () {
  57. Vue.util.defineReactive(this, 'nuxt', this.$root.$options.nuxt)
  58. },
  59. render (h) {
  60. // if there is no error
  61. if (!this.nuxt.err) {
  62. // Directly return nuxt child
  63. return h('NuxtChild', {
  64. key: this.routerViewKey,
  65. props: this.$props
  66. })
  67. }
  68. // if an error occurred within NuxtError show a simple
  69. // error message instead to prevent looping
  70. if (this.errorFromNuxtError) {
  71. this.$nextTick(() => (this.errorFromNuxtError = false))
  72. return h('div', {}, [
  73. h('h2', 'An error occurred while showing the error page'),
  74. h('p', 'Unfortunately an error occurred and while showing the error page another error occurred'),
  75. h('p', `Error details: ${this.errorFromNuxtError.toString()}`),
  76. h('nuxt-link', { props: { to: '/' } }, 'Go back to home')
  77. ])
  78. }
  79. // track if we are showing the NuxtError component
  80. this.displayingNuxtError = true
  81. this.$nextTick(() => (this.displayingNuxtError = false))
  82. return h(NuxtError, {
  83. props: {
  84. error: this.nuxt.err
  85. }
  86. })
  87. }
  88. }