Fix reused component data

This commit is contained in:
Sébastien Chopin 2016-11-23 00:27:07 +01:00
parent b6affe88dd
commit fc598ea66e
4 changed files with 35 additions and 4 deletions

View File

@ -4,7 +4,7 @@ require('es6-object-assign').polyfill()
import 'es6-promise/auto' import 'es6-promise/auto'
import Vue from 'vue' import Vue from 'vue'
import { app, router<%= (store ? ', store' : '') %> } from './index' import { app, router<%= (store ? ', store' : '') %> } from './index'
import { getMatchedComponents, flatMapComponents, getContext, promisify, getLocation } from './utils' import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promisify, getLocation } from './utils'
const noopData = () => { return {} } const noopData = () => { return {} }
const noopFetch = () => {} const noopFetch = () => {}
@ -111,6 +111,28 @@ function render (to, ___, next) {
}) })
} }
// When navigating on a different route but the same component is used, Vue.js
// will not update the instance data, so we have to update $data ourselves
function fixPrepatch (to, ___) {
if (!this.$nuxt._routerViewCache || !this.$nuxt._routerViewCache.default) {
return
}
Vue.nextTick(() => {
let RouterViewComponentFile = this.$nuxt._routerViewCache.default.__file
if (typeof this.$nuxt._routerViewCache.default === 'function') RouterViewComponentFile = this.$nuxt._routerViewCache.default.options.__file
let instances = getMatchedComponentsInstances(to)
instances.forEach((instance, i) => {
if (!instance) return;
if (instance.constructor.options.__file === RouterViewComponentFile) {
let newData = instance.constructor.options.data()
for (let key in newData) {
Vue.set(instance.$data, key, newData[key])
}
}
})
})
}
// Special hot reload with data(context) // Special hot reload with data(context)
function hotReloadAPI (_app) { function hotReloadAPI (_app) {
const $nuxt = _app.$nuxt const $nuxt = _app.$nuxt
@ -123,7 +145,6 @@ function hotReloadAPI (_app) {
Component = Vue.extend(Component) Component = Vue.extend(Component)
Component._Ctor = Component Component._Ctor = Component
} }
<%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
let promises = [] let promises = []
const next = function (path) { const next = function (path) {
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %> <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
@ -155,6 +176,8 @@ function hotReloadAPI (_app) {
<%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %> <%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
promises.push(p) promises.push(p)
} }
if (!promises.length) return;
<%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
return Promise.all(promises).then(() => { return Promise.all(promises).then(() => {
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %> <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
_forceUpdate() _forceUpdate()
@ -229,6 +252,7 @@ Promise.all(resolveComponents)
// Add router hooks // Add router hooks
router.beforeEach(loadAsyncComponents.bind(_app)) router.beforeEach(loadAsyncComponents.bind(_app))
router.beforeEach(render.bind(_app)) router.beforeEach(render.bind(_app))
router.afterEach(fixPrepatch.bind(_app))
if (NUXT.serverRendered) { if (NUXT.serverRendered) {
mountApp() mountApp()
return return

View File

@ -8,6 +8,14 @@ export function getMatchedComponents (route) {
})) }))
} }
export function getMatchedComponentsInstances (route) {
return [].concat.apply([], route.matched.map(function (m) {
return Object.keys(m.instances).map(function (key) {
return m.instances[key]
})
}))
}
export function flatMapComponents (route, fn) { export function flatMapComponents (route, fn) {
return Array.prototype.concat.apply([], route.matched.map(function (m, index) { return Array.prototype.concat.apply([], route.matched.map(function (m, index) {
return Object.keys(m.components).map(function (key) { return Object.keys(m.components).map(function (key) {

View File

@ -312,7 +312,6 @@ function watchPages () {
ignoreInitial: true ignoreInitial: true
} }
const refreshFiles = _.debounce(() => { const refreshFiles = _.debounce(() => {
console.log('Reload files', this.routes.length)
var d = Date.now() var d = Date.now()
co(generateRoutesAndFiles.bind(this)) co(generateRoutesAndFiles.bind(this))
.then(() => { .then(() => {

View File

@ -1,6 +1,6 @@
{ {
"name": "nuxt", "name": "nuxt",
"version": "0.6.5", "version": "0.6.6",
"description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)", "description": "A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js)",
"main": "index.js", "main": "index.js",
"license": "MIT", "license": "MIT",