Skip to content

Commit 88f99da

Browse files
committed
hot reload: handle router-view
1 parent d67b6ea commit 88f99da

File tree

1 file changed

+73
-36
lines changed

1 file changed

+73
-36
lines changed

lib/hot-reload-api.js

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,53 +21,90 @@ exports.install = function (Vue) {
2121

2222
// create global hot reload map
2323
var map = Vue.config._hotComponents = Object.create(null)
24-
// check compatibility
25-
var componentDir = Vue.internalDirectives.component
24+
// shim component
25+
shimComponent(Vue.internalDirectives.component, map)
26+
console.log('[HMR] vue component hot reload shim applied.')
27+
// shim router-view if present
28+
var routerView = Vue.elementDirective('router-view')
29+
if (routerView) {
30+
shimComponent(routerView, map)
31+
console.log('[HMR] vue-router <router-view> hot reload shim applied.')
32+
}
33+
}
2634

27-
// shim the component directive
28-
var set = componentDir.setComponent
29-
componentDir.setComponent = function (id, cb) {
30-
var prevComponent = this.Component
31-
var prevId = prevComponent && prevComponent.options.hotID
32-
if (prevId) {
33-
map[prevId].instances.$remove(this)
35+
/**
36+
* Shim the component directive.
37+
*
38+
* @param {Object} dir
39+
* @param {Object} map - hot component map
40+
*/
41+
42+
function shimComponent (dir, map) {
43+
shimMethod(dir, 'unbuild', function (defer) {
44+
var prevComponent = this.childVM && this.childVM.constructor
45+
removeComponent(prevComponent, map, this)
46+
// defer = true means we are transitioning to a new
47+
// Component. Register this new component to the list.
48+
if (defer) {
49+
addComponent(this.Component, map, this)
3450
}
35-
set.call(this, id, cb)
51+
})
52+
}
53+
54+
/**
55+
* Shim a directive method.
56+
*
57+
* @param {Object} dir
58+
* @param {String} methodName
59+
* @param {Function} fn
60+
*/
61+
62+
function shimMethod (dir, methodName, fn) {
63+
var original = dir[methodName]
64+
dir[methodName] = function () {
65+
fn.apply(this, arguments)
66+
return original.apply(this, arguments)
3667
}
68+
}
3769

38-
var resolve = componentDir.resolveComponent
39-
componentDir.resolveComponent = function (id, cb) {
40-
var view = this
41-
resolve.call(this, id, function () {
42-
var Component = view.Component
43-
var newId = Component.options.hotID
44-
if (newId) {
45-
if (!map[newId]) {
46-
map[newId] = {
47-
Ctor: Component,
48-
instances: []
49-
}
50-
}
51-
map[newId].instances.push(view)
52-
}
53-
cb()
54-
})
70+
/**
71+
* Remove a component view from a Component's hot list
72+
*
73+
* @param {Function} Component
74+
* @param {Object} map - hot component map
75+
* @param {Directive} view - view directive instance
76+
*/
77+
78+
function removeComponent (Component, map, view) {
79+
var id = Component && Component.options.hotID
80+
if (id) {
81+
map[id].instances.$remove(view)
5582
}
83+
}
5684

57-
var unbind = componentDir.unbind
58-
componentDir.unbind = function () {
59-
var id = this.Component && this.Component.options.hotID
60-
if (id) {
61-
map[id].instances.$remove(this)
85+
/**
86+
* Add a component view to a Component's hot list
87+
*
88+
* @param {Function} Component
89+
* @param {Object} map - hot component map
90+
* @param {Directive} view - view directive instance
91+
*/
92+
93+
function addComponent (Component, map, view) {
94+
var id = Component && Component.options.hotID
95+
if (id) {
96+
if (!map[id]) {
97+
map[id] = {
98+
Ctor: Component,
99+
instances: []
100+
}
62101
}
63-
unbind.call(this)
102+
map[id].instances.push(view)
64103
}
65-
66-
console.log('[HMR] Vue component hot reload shim applied.')
67104
}
68105

69106
/**
70-
* Update a component directive instance
107+
* Update a component view instance
71108
*
72109
* @param {Directive} view
73110
*/

0 commit comments

Comments
 (0)