Skip to content

Commit 8c411fb

Browse files
committed
merge data, activate & deactivate hooks
1 parent 8e5cf9d commit 8c411fb

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

src/override.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export default function (Vue) {
22

33
const _ = Vue.util
44

5+
// override Vue's init and destroy process to keep track of router instances
56
const init = Vue.prototype._init
67
Vue.prototype._init = function (options) {
78
const root = options._parent || options.parent || this
@@ -32,4 +33,26 @@ export default function (Vue) {
3233
destroy.apply(this, arguments)
3334
}
3435
}
36+
37+
// 1.0 only: enable route mixins
38+
const strats = Vue.config.optionMergeStrategies
39+
const hooksToMergeRE = /^(data|activate|deactivate)$/
40+
if (strats) {
41+
strats.route = (parentVal, childVal) => {
42+
if (!childVal) return parentVal
43+
if (!parentVal) return childVal
44+
const ret = {}
45+
_.extend(ret, parentVal)
46+
for (let key in childVal) {
47+
let a = ret[key]
48+
let b = childVal[key]
49+
if (a && hooksToMergeRE.test(key)) {
50+
ret[key] = (_.isArray(a) ? a : [a]).concat(b)
51+
} else {
52+
ret[key] = b
53+
}
54+
}
55+
return ret
56+
}
57+
}
3558
}

src/pipeline.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export function deactivate (view, transition, next) {
8888
if (!hook) {
8989
next()
9090
} else {
91-
transition.callHook(hook, component, next)
91+
transition.callHooks(hook, component, next)
9292
}
9393
}
9494

@@ -226,7 +226,7 @@ export function activate (view, transition, depth, cb, reuse) {
226226
}
227227

228228
if (activateHook) {
229-
transition.callHook(activateHook, component, afterActivate, {
229+
transition.callHooks(activateHook, component, afterActivate, {
230230
cleanup: cleanup
231231
})
232232
} else {
@@ -261,9 +261,21 @@ export function reuse (view, transition) {
261261

262262
function loadData (component, transition, hook, cb, cleanup) {
263263
component.$loadingRouteData = true
264-
transition.callHook(hook, component, (data, onError) => {
264+
transition.callHooks(hook, component, (data, onError) => {
265+
// merge data from multiple data hooks
266+
if (Array.isArray(data) && data._needMerge) {
267+
data = data.reduce(function (res, obj) {
268+
if (isPlainObject(obj)) {
269+
Object.keys(obj).forEach(key => {
270+
res[key] = obj[key]
271+
})
272+
}
273+
return res
274+
}, Object.create(null))
275+
}
276+
// handle promise sugar syntax
265277
let promises = []
266-
if (Object.prototype.toString.call(data) === '[object Object]') {
278+
if (isPlainObject(data)) {
267279
Object.keys(data).forEach(key => {
268280
let val = data[key]
269281
if (isPromise(val)) {
@@ -289,3 +301,7 @@ function loadData (component, transition, hook, cb, cleanup) {
289301
expectData: true
290302
})
291303
}
304+
305+
function isPlainObject (obj) {
306+
return Object.prototype.toString.call(obj) === '[object Object]'
307+
}

src/transition.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,11 @@ export default class RouteTransition {
230230
return
231231
}
232232
nextCalled = true
233-
if (!cb || transition.aborted) {
233+
if (transition.aborted) {
234+
cleanup && cleanup()
234235
return
235236
}
236-
cb(data, onError)
237+
cb && cb(data, onError)
237238
}
238239

239240
// expose a clone of the transition object, so that each
@@ -263,7 +264,7 @@ export default class RouteTransition {
263264
if (typeof res === 'boolean') {
264265
res ? next() : abort()
265266
} else if (resIsPromise) {
266-
res.then(function (ok) {
267+
res.then((ok) => {
267268
ok ? next() : abort()
268269
}, onError)
269270
} else if (!hook.length) {
@@ -275,6 +276,36 @@ export default class RouteTransition {
275276
next(res)
276277
}
277278
}
279+
280+
/**
281+
* Call a single hook or an array of async hooks in series.
282+
*
283+
* @param {Array} hooks
284+
* @param {*} context
285+
* @param {Function} cb
286+
* @param {Object} [options]
287+
*/
288+
289+
callHooks (hooks, context, cb, options) {
290+
if (Array.isArray(hooks)) {
291+
let res = []
292+
res._needMerge = true
293+
let onError
294+
this.runQueue(hooks, (hook, _, next) => {
295+
if (!this.aborted) {
296+
this.callHook(hook, context, (r, onError) => {
297+
if (r) res.push(r)
298+
onError = onError
299+
next()
300+
}, options)
301+
}
302+
}, () => {
303+
cb(res, onError)
304+
})
305+
} else {
306+
this.callHook(hooks, context, cb, options)
307+
}
308+
}
278309
}
279310

280311
function isPlainOjbect (val) {

0 commit comments

Comments
 (0)