fix unexpected state reset #1408

This commit is contained in:
devneko 2017-10-29 11:02:48 +09:00
parent c0065127f1
commit f186cadba6
2 changed files with 47 additions and 4 deletions

View File

@ -6,7 +6,7 @@ import {
sanitizeComponent, sanitizeComponent,
resolveRouteComponents, resolveRouteComponents,
getMatchedComponents, getMatchedComponents,
getMatchedComponentsInstances, getChangedComponentsInstances,
flatMapComponents, flatMapComponents,
setContext, setContext,
middlewareSeries, middlewareSeries,
@ -346,16 +346,17 @@ function showNextPage(to) {
// When navigating on a different route but the same component is used, Vue.js // 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 // Will not update the instance data, so we have to update $data ourselves
function fixPrepatch (to, ___) { function fixPrepatch (to, from) {
if (this._hashChanged) return if (this._hashChanged) return
Vue.nextTick(() => { Vue.nextTick(() => {
const instances = getMatchedComponentsInstances(to) const instances = getChangedComponentsInstances(to, from)
var dlen = to.matched.length - instances.length
_lastComponentsFiles = instances.map((instance, i) => { _lastComponentsFiles = instances.map((instance, i) => {
if (!instance) return ''; if (!instance) return '';
if (_lastPaths[i] === instance.constructor._path && typeof instance.constructor.options.data === 'function') { if (_lastPaths[dlen + i] === instance.constructor._path && typeof instance.constructor.options.data === 'function') {
const newData = instance.constructor.options.data.call(instance) const newData = instance.constructor.options.data.call(instance)
for (let key in newData) { for (let key in newData) {
Vue.set(instance.$data, key, newData[key]) Vue.set(instance.$data, key, newData[key])

View File

@ -65,6 +65,48 @@ export function getMatchedComponentsInstances(route) {
})) }))
} }
function getRouteRecordWithParamNames (route) {
return route.matched.map(m => {
var paramNames = m.path.match(new RegExp(':[^\\/\\?]+', 'g'))
if (paramNames !== null) {
paramNames = paramNames.map(function (name) {
return name.substring(1)
})
}
return {
routeRecord: m,
paramNames: paramNames
}
})
}
export function getChangedComponentsInstances (to, from) {
var records = getRouteRecordWithParamNames(to)
var r = []
var parentChange = false
for (var i = 0; i < records.length; i++ ) {
var paramNames = records[i].paramNames
var instances = records[i].routeRecord.instances
instances = Object.keys(instances).map(function (key) {
return instances[key]
})
if (parentChange) {
r = [].concat(r, instances)
} else if (paramNames !== null) {
for (var pi in paramNames) {
var name = paramNames[pi]
if (to.params[name] !== from.params[name]) {
parentChange = true
r = [].concat(r, instances)
break
}
}
}
}
return r
}
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) {