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.

48 lines
1.3 KiB

4 weeks ago
  1. import Vue from 'vue'
  2. import { hasFetch, normalizeError, addLifecycleHook } from '../utils'
  3. async function serverPrefetch() {
  4. if (!this._fetchOnServer) {
  5. return
  6. }
  7. // Call and await on $fetch
  8. try {
  9. await this.$options.fetch.call(this)
  10. } catch (err) {
  11. this.$fetchState.error = normalizeError(err)
  12. }
  13. this.$fetchState.pending = false
  14. // Define an ssrKey for hydration
  15. this._fetchKey = this.$ssrContext.nuxt.fetch.length
  16. // Add data-fetch-key on parent element of Component
  17. const attrs = this.$vnode.data.attrs = this.$vnode.data.attrs || {}
  18. attrs['data-fetch-key'] = this._fetchKey
  19. // Add to ssrContext for window.__NUXT__.fetch
  20. this.$ssrContext.nuxt.fetch.push(this.$fetchState.error ? { _error: this.$fetchState.error } : this._data)
  21. }
  22. export default {
  23. beforeCreate() {
  24. if (!hasFetch(this)) {
  25. return
  26. }
  27. if (typeof this.$options.fetchOnServer === 'function') {
  28. this._fetchOnServer = this.$options.fetchOnServer.call(this) !== false
  29. } else {
  30. this._fetchOnServer = this.$options.fetchOnServer !== false
  31. }
  32. Vue.util.defineReactive(this, '$fetchState', {
  33. pending: true,
  34. error: null,
  35. timestamp: Date.now()
  36. })
  37. addLifecycleHook(this, 'serverPrefetch', serverPrefetch)
  38. }
  39. }