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 Vue from 'vue'
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 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)
function hotReloadAPI (_app) {
const $nuxt = _app.$nuxt
@ -123,7 +145,6 @@ function hotReloadAPI (_app) {
Component = Vue.extend(Component)
Component._Ctor = Component
}
<%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
let promises = []
const next = function (path) {
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
@ -155,6 +176,8 @@ function hotReloadAPI (_app) {
<%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
promises.push(p)
}
if (!promises.length) return;
<%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
return Promise.all(promises).then(() => {
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
_forceUpdate()
@ -229,6 +252,7 @@ Promise.all(resolveComponents)
// Add router hooks
router.beforeEach(loadAsyncComponents.bind(_app))
router.beforeEach(render.bind(_app))
router.afterEach(fixPrepatch.bind(_app))
if (NUXT.serverRendered) {
mountApp()
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) {
return Array.prototype.concat.apply([], route.matched.map(function (m, index) {
return Object.keys(m.components).map(function (key) {

View File

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

View File

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