diff --git a/lib/app/client.js b/lib/app/client.js index 01e755d2f9..224315c80e 100644 --- a/lib/app/client.js +++ b/lib/app/client.js @@ -4,9 +4,20 @@ require('es6-object-assign').polyfill() import 'es6-promise/auto' import Vue from 'vue' import { app, router<%= (store ? ', store' : '') %> } from './index' -import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promisify, getLocation } from './utils' +import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promisify, getLocation, compile } from './utils' const noopData = () => { return {} } const noopFetch = () => {} +let _lastPaths = [] + +function mapTransitions(Components, to, from) { + return Components.map((Component) => { + let transition = Component.options.transition + if (typeof transition === 'function') { + return transition(to, from) + } + return transition + }) +} function loadAsyncComponents (to, ___, next) { const resolveComponents = flatMapComponents(to, (Component, _, match, key) => { @@ -44,7 +55,7 @@ function loadAsyncComponents (to, ___, next) { }) } -function render (to, ___, next) { +function render (to, from, next) { let Components = getMatchedComponents(to) if (!Components.length) { this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path }) @@ -67,7 +78,7 @@ function render (to, ___, next) { } } }) - this.setTransition(Components[0].options.transition) + this.setTransitions(mapTransitions(Components, to, from)) this.error() let nextCalled = false let isValid = Components.some((Component) => { @@ -81,7 +92,12 @@ function render (to, ___, next) { this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path }) return next() } - Promise.all(Components.map((Component) => { + Promise.all(Components.map((Component, i) => { + // Check if only children route changed + Component._path = compile(to.matched[i].path)(to.params) + if (Component._path === _lastPaths[i] && (i + 1) !== Components.length) { + return Promise.resolve() + } let promises = [] const _next = function (path) { <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %> @@ -111,6 +127,7 @@ function render (to, ___, next) { return Promise.all(promises) })) .then(() => { + _lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params)) <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %> // If not redirected if (!nextCalled) { @@ -118,6 +135,7 @@ function render (to, ___, next) { } }) .catch((error) => { + _lastPaths = [] this.error(error) next(false) }) @@ -268,8 +286,11 @@ Promise.all(resolveComponents) store.replaceState(NUXT.state) } <% } %> - _app.setTransition = _app.$options._nuxt.setTransition.bind(_app) - if (Components.length) _app.setTransition(Components[0].options.transition) + _app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app) + if (Components.length) { + _app.setTransitions(mapTransitions(Components, router.currentRoute)) + _lastPaths = router.currentRoute.matched.map((route) => compile(route.path)(router.currentRoute.params)) + } _app.error = _app.$options._nuxt.error.bind(_app) _app.$loading = {} // to avoid error while _app.$nuxt does not exist if (NUXT.error) _app.error(NUXT.error)