@nuxt/vue-app
Advanced tools
Comparing version 2.11.0 to 2.12.0
/*! | ||
* @nuxt/vue-app v2.11.0 (c) 2016-2019 | ||
* @nuxt/vue-app v2.12.0 (c) 2016-2020 | ||
@@ -21,7 +21,7 @@ * - All the amazing contributors | ||
"vue-client-only": "^2.0.0", | ||
"vue-meta": "^2.3.1", | ||
"vue-meta": "^2.3.3", | ||
"vue-no-ssr": "^1.1.1", | ||
"vue-router": "^3.1.3", | ||
"vue-router": "^3.1.6", | ||
"vue-template-compiler": "^2.6.11", | ||
vuex: "^3.1.2" | ||
vuex: "^3.1.3" | ||
}; | ||
@@ -41,2 +41,4 @@ | ||
'empty.js', | ||
'mixins/fetch.server.js', | ||
'mixins/fetch.client.js', | ||
'components/nuxt-error.vue', | ||
@@ -43,0 +45,0 @@ 'components/nuxt-child.js', |
{ | ||
"name": "@nuxt/vue-app", | ||
"version": "2.11.0", | ||
"version": "2.12.0", | ||
"repository": "nuxt/nuxt.js", | ||
"license": "MIT", | ||
"main": "dist/vue-app.js", | ||
"typings": "index.d.ts", | ||
"files": [ | ||
@@ -12,4 +14,2 @@ "dist", | ||
], | ||
"main": "dist/vue-app.js", | ||
"typings": "index.d.ts", | ||
"dependencies": { | ||
@@ -20,7 +20,7 @@ "node-fetch": "^2.6.0", | ||
"vue-client-only": "^2.0.0", | ||
"vue-meta": "^2.3.1", | ||
"vue-meta": "^2.3.3", | ||
"vue-no-ssr": "^1.1.1", | ||
"vue-router": "^3.1.3", | ||
"vue-router": "^3.1.6", | ||
"vue-template-compiler": "^2.6.11", | ||
"vuex": "^3.1.2" | ||
"vuex": "^3.1.3" | ||
}, | ||
@@ -27,0 +27,0 @@ "publishConfig": { |
@@ -5,2 +5,3 @@ import Vue from 'vue' | ||
getMatchedComponentsInstances, | ||
getChildrenComponentInstancesUsingFetch, | ||
promisify, | ||
@@ -32,7 +33,2 @@ globalHandleError | ||
export default { | ||
<% if (features.meta) { %> | ||
<%= isTest ? '/* eslint-disable array-bracket-spacing, quotes, quote-props, semi, indent, comma-spacing, key-spacing, object-curly-spacing, space-before-function-paren, object-shorthand */' : '' %> | ||
head: <%= serializeFunction(head) %>, | ||
<%= isTest ? '/* eslint-enable array-bracket-spacing, quotes, quote-props, semi, indent, comma-spacing, key-spacing, object-curly-spacing, space-before-function-paren, object-shorthand */' : '' %> | ||
<% } %> | ||
render (h, props) { | ||
@@ -98,5 +94,8 @@ <% if (loading) { %>const loadingEl = h('NuxtLoading', { ref: 'loading' })<% } %> | ||
layout: null, | ||
layoutName: '' | ||
layoutName: '', | ||
<% } %> | ||
}), | ||
<% if (features.fetch) { %> | ||
nbFetching: 0 | ||
<% } %> | ||
}), | ||
<% } %> | ||
@@ -136,3 +135,8 @@ beforeCreate () { | ||
return !this.isOnline | ||
}, | ||
<% if (features.fetch) { %> | ||
isFetching() { | ||
return this.nbFetching > 0 | ||
} | ||
<% } %> | ||
}, | ||
@@ -169,5 +173,14 @@ <% } %> | ||
<% if (features.fetch) { %> | ||
if (page.$options.fetch) { | ||
// Old fetch | ||
if (page.$options.fetch && page.$options.fetch.length) { | ||
p.push(promisify(page.$options.fetch, this.context)) | ||
} | ||
if (page.$fetch) { | ||
p.push(page.$fetch()) | ||
} else { | ||
// Get all component instance to call $fetch | ||
for (const component of getChildrenComponentInstancesUsingFetch(page.$vnode.componentInstance)) { | ||
p.push(component.$fetch()) | ||
} | ||
} | ||
<% } %> | ||
@@ -191,3 +204,3 @@ <% if (features.asyncData) { %> | ||
} catch (error) { | ||
<% if (loading) { %>this.$loading.fail()<% } %> | ||
<% if (loading) { %>this.$loading.fail(error)<% } %> | ||
globalHandleError(error) | ||
@@ -203,3 +216,3 @@ this.error(error) | ||
if (this.$loading.fail) { | ||
this.$loading.fail() | ||
this.$loading.fail(this.nuxt.err) | ||
} | ||
@@ -206,0 +219,0 @@ if (this.$loading.finish) { |
@@ -20,4 +20,13 @@ import Vue from 'vue' | ||
import { createApp<% if (features.layouts) { %>, NuxtError<% } %> } from './index.js' | ||
<% if (features.fetch) { %>import fetchMixin from './mixins/fetch.client'<% } %> | ||
import NuxtLink from './components/nuxt-link.<%= features.clientPrefetch ? "client" : "server" %>.js' // should be included after ./index.js | ||
<% if (features.fetch) { %> | ||
// Fetch mixin | ||
if (!Vue.__nuxt__fetch__mixin__) { | ||
Vue.mixin(fetchMixin) | ||
Vue.__nuxt__fetch__mixin__ = true | ||
} | ||
<% } %> | ||
// Component: <NuxtLink> | ||
@@ -106,3 +115,3 @@ Vue.component(NuxtLink.name, NuxtLink) | ||
function mapTransitions (Components, to, from) { | ||
function mapTransitions (toComponents, to, from) { | ||
const componentTransitions = (component) => { | ||
@@ -113,26 +122,30 @@ const transition = componentOption(component, 'transition', to, from) || {} | ||
return Components.map((Component) => { | ||
// Clone original object to prevent overrides | ||
const transitions = Object.assign({}, componentTransitions(Component)) | ||
const fromComponents = from ? getMatchedComponents(from) : [] | ||
const maxDepth = Math.max(toComponents.length, fromComponents.length) | ||
// Combine transitions & prefer `leave` transitions of 'from' route | ||
if (from && from.matched.length && from.matched[0].components.default) { | ||
const fromTransitions = componentTransitions(from.matched[0].components.default) | ||
Object.keys(fromTransitions) | ||
.filter(key => fromTransitions[key] && key.toLowerCase().includes('leave')) | ||
.forEach((key) => { transitions[key] = fromTransitions[key] }) | ||
} | ||
const mergedTransitions = [] | ||
for (let i=0; i<maxDepth; i++) { | ||
// Clone original objects to prevent overrides | ||
const toTransitions = Object.assign({}, componentTransitions(toComponents[i])) | ||
const transitions = Object.assign({}, componentTransitions(fromComponents[i])) | ||
return transitions | ||
}) | ||
// Combine transitions & prefer `leave` properties of "from" route | ||
Object.keys(toTransitions) | ||
.filter(key => typeof toTransitions[key] !== 'undefined' && !key.toLowerCase().includes('leave')) | ||
.forEach((key) => { transitions[key] = toTransitions[key] }) | ||
mergedTransitions.push(transitions) | ||
} | ||
return mergedTransitions | ||
} | ||
<% } %> | ||
<% if (loading) { %>async <% } %>function loadAsyncComponents (to, from, next) { | ||
// Check if route path changed (this._pathChanged), only if the page is not an error (for validate()) | ||
this._pathChanged = Boolean(app.nuxt.err) || from.path !== to.path | ||
this._queryChanged = JSON.stringify(to.query) !== JSON.stringify(from.query) | ||
// Check if route changed (this._routeChanged), only if the page is not an error (for validate()) | ||
this._routeChanged = Boolean(app.nuxt.err) || from.name !== to.name | ||
this._paramChanged = !this._routeChanged && from.path !== to.path | ||
this._queryChanged = !this._paramChanged && from.fullPath !== to.fullPath | ||
this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : []) | ||
<% if (loading) { %> | ||
if (this._pathChanged && this.$loading.start && !this.$loading.manual) { | ||
if ((this._routeChanged || this._paramChanged) && this.$loading.start && !this.$loading.manual) { | ||
this.$loading.start() | ||
@@ -144,3 +157,3 @@ } | ||
<% if (loading) { %> | ||
if (!this._pathChanged && this._queryChanged) { | ||
if (this._queryChanged) { | ||
const Components = await resolveRouteComponents( | ||
@@ -263,3 +276,3 @@ to, | ||
async function render (to, from, next) { | ||
if (this._pathChanged === false && this._queryChanged === false) { | ||
if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) { | ||
return next() | ||
@@ -428,7 +441,13 @@ } | ||
Component._dataRefresh = false | ||
// Check if Component need to be refreshed (call asyncData & fetch) | ||
// Only if its slug has changed or is watch query changes | ||
if ((this._pathChanged && this._queryChanged) || Component._path !== _lastPaths[i]) { | ||
const childPathChanged = Component._path !== _lastPaths[i] | ||
// Refresh component (call asyncData & fetch) when: | ||
// Route path changed part includes current component | ||
// Or route param changed part includes current component and watchParam is not `false` | ||
// Or route query is changed and watchQuery returns `true` | ||
if (this._routeChanged && childPathChanged) { | ||
Component._dataRefresh = true | ||
} else if (!this._pathChanged && this._queryChanged) { | ||
} else if (this._paramChanged && childPathChanged) { | ||
const watchParam = Component.options.watchParam | ||
Component._dataRefresh = watchParam !== false | ||
} else if (this._queryChanged) { | ||
const watchQuery = Component.options.watchQuery | ||
@@ -462,3 +481,3 @@ if (watchQuery === true) { | ||
<% if (features.fetch) { %> | ||
const hasFetch = Boolean(Component.options.fetch) | ||
const hasFetch = Boolean(Component.options.fetch) && Component.options.fetch.length | ||
<% } else { %> | ||
@@ -582,3 +601,3 @@ const hasFetch = false | ||
function fixPrepatch (to, ___) { | ||
if (this._pathChanged === false && this._queryChanged === false) { | ||
if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) { | ||
return | ||
@@ -744,3 +763,3 @@ } | ||
Component.options.fetch = Component.options.fetch || noopFetch | ||
let pFetch = Component.options.fetch(context) | ||
let pFetch = Component.options.fetch.length && Component.options.fetch(context) | ||
if (!pFetch || (!(pFetch instanceof Promise) && (typeof pFetch.then !== 'function'))) { pFetch = Promise.resolve(pFetch) } | ||
@@ -818,4 +837,4 @@ <%= (loading ? 'pFetch.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %> | ||
// If page already is server rendered | ||
if (NUXT.serverRendered) { | ||
// If page already is server rendered and it was done on the same route path as client side render | ||
if (NUXT.serverRendered && NUXT.routePath === _app.context.route.path) { | ||
mount() | ||
@@ -822,0 +841,0 @@ return |
@@ -16,3 +16,4 @@ <%= isTest ? '// @vue/component' : '' %> | ||
}, | ||
render (h, { parent, data, props }) { | ||
render (_, { parent, data, props }) { | ||
const h = parent.$createElement | ||
<% if (features.transitions) { %> | ||
@@ -46,11 +47,13 @@ data.nuxtChild = true | ||
}) | ||
// Add triggerScroll event on beforeEnter (fix #1376) | ||
const beforeEnter = listeners.beforeEnter | ||
listeners.beforeEnter = (el) => { | ||
// Ensure to trigger scroll event after calling scrollBehavior | ||
window.<%= globals.nuxt %>.$nextTick(() => { | ||
window.<%= globals.nuxt %>.$emit('triggerScroll') | ||
}) | ||
if (beforeEnter) { | ||
return beforeEnter.call(_parent, el) | ||
if (process.client) { | ||
// Add triggerScroll event on beforeEnter (fix #1376) | ||
const beforeEnter = listeners.beforeEnter | ||
listeners.beforeEnter = (el) => { | ||
// Ensure to trigger scroll event after calling scrollBehavior | ||
window.<%= globals.nuxt %>.$nextTick(() => { | ||
window.<%= globals.nuxt %>.$emit('triggerScroll') | ||
}) | ||
if (beforeEnter) { | ||
return beforeEnter.call(_parent, el) | ||
} | ||
} | ||
@@ -57,0 +60,0 @@ } |
@@ -88,2 +88,7 @@ import Vue from 'vue' | ||
const app = { | ||
<% if (features.meta) { %> | ||
<%= isTest ? '/* eslint-disable array-bracket-spacing, quotes, quote-props, semi, indent, comma-spacing, key-spacing, object-curly-spacing, space-before-function-paren, object-shorthand */' : '' %> | ||
head: <%= serializeFunction(head) %>, | ||
<%= isTest ? '/* eslint-enable array-bracket-spacing, quotes, quote-props, semi, indent, comma-spacing, key-spacing, object-curly-spacing, space-before-function-paren, object-shorthand */' : '' %> | ||
<% } %> | ||
<% if (store) { %>store,<% } %> | ||
@@ -119,3 +124,6 @@ router, | ||
err = err ? normalizeError(err) : null | ||
const nuxt = this.nuxt || this.$options.nuxt | ||
let nuxt = app.nuxt // to work with @vue/composition-api, see https://github.com/nuxt/nuxt.js/issues/6517#issuecomment-573280207 | ||
if (this) { | ||
nuxt = this.nuxt || this.$options.nuxt | ||
} | ||
nuxt.dateErr = Date.now() | ||
@@ -165,3 +173,3 @@ nuxt.err = err | ||
if (value === undefined) { | ||
throw new Error('inject(key, value) has no value provided') | ||
throw new Error(`inject('${key}', value) has no value provided`) | ||
} | ||
@@ -168,0 +176,0 @@ |
@@ -12,5 +12,17 @@ import { stringify } from 'querystring' | ||
} from './utils.js' | ||
<% if (features.fetch) { %>import fetchMixin from './mixins/fetch.server'<% } %> | ||
import { createApp<% if (features.layouts) { %>, NuxtError<% } %> } from './index.js' | ||
import NuxtLink from './components/nuxt-link.server.js' // should be included after ./index.js | ||
<% if (features.fetch) { %> | ||
// Update serverPrefetch strategy | ||
Vue.config.optionMergeStrategies.serverPrefetch = Vue.config.optionMergeStrategies.created | ||
// Fetch mixin | ||
if (!Vue.__nuxt__fetch__mixin__) { | ||
Vue.mixin(fetchMixin) | ||
Vue.__nuxt__fetch__mixin__ = true | ||
} | ||
<% } %> | ||
// Component: <NuxtLink> | ||
@@ -64,6 +76,8 @@ Vue.component(NuxtLink.name, NuxtLink) | ||
// Nuxt object (window{{globals.context}}, defaults to window.__NUXT__) | ||
ssrContext.nuxt = { <% if (features.layouts) { %>layout: 'default', <% } %>data: [], error: null<%= (store ? ', state: null' : '') %>, serverRendered: true } | ||
ssrContext.nuxt = { <% if (features.layouts) { %>layout: 'default', <% } %>data: [], <% if (features.fetch) { %>fetch: [], <% } %>error: null<%= (store ? ', state: null' : '') %>, serverRendered: true, routePath: '' } | ||
// Create the app definition and the instance (created for each request) | ||
const { app, router<%= (store ? ', store' : '') %> } = await createApp(ssrContext) | ||
const _app = new Vue(app) | ||
// Add ssr route path to nuxt context so we can account for page navigation between ssr and csr | ||
ssrContext.nuxt.routePath = app.context.route.path | ||
@@ -272,3 +286,3 @@ <% if (features.meta) { %> | ||
// Call fetch(context) | ||
if (Component.options.fetch) { | ||
if (Component.options.fetch && Component.options.fetch.length) { | ||
promises.push(Component.options.fetch(app.context)) | ||
@@ -275,0 +289,0 @@ } else { |
@@ -24,2 +24,20 @@ import Vue from 'vue' | ||
<% if (features.fetch) { %> | ||
export function hasFetch(vm) { | ||
return vm.$options && typeof vm.$options.fetch === 'function' && !vm.$options.fetch.length | ||
} | ||
export function getChildrenComponentInstancesUsingFetch(vm, instances = []) { | ||
const children = vm.$children || [] | ||
for (const child of children) { | ||
if (child.$fetch) { | ||
instances.push(child) | ||
continue; // Don't get the children since it will reload the template | ||
} | ||
if (child.$children) { | ||
getChildrenComponentInstancesUsingFetch(child, instances) | ||
} | ||
} | ||
return instances | ||
} | ||
<% } %> | ||
<% if (features.asyncData) { %> | ||
@@ -619,1 +637,8 @@ export function applyAsyncData (Component, asyncData) { | ||
<% } %> | ||
export function addLifecycleHook(vm, hook, fn) { | ||
if (!vm.$options[hook]) { | ||
vm.$options[hook] = [] | ||
} | ||
vm.$options[hook].push(fn) | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
145781
41
3021
9
Updatedvue-meta@^2.3.3
Updatedvue-router@^3.1.6
Updatedvuex@^3.1.3