Skip to content

Commit d9c7a5d

Browse files
committed
Merge branch 'dev'
2 parents d4eb1d3 + 25b5c2c commit d9c7a5d

10 files changed

+112
-13477
lines changed

.editorconfig

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 4
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.md]
13+
trim_trailing_whitespace = false

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
node_modules
33
npm-debug.log
4+
test/build.js

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Vue.use(route); // BOOM
6969
* *data*: an object that will be **merged** with the view's `$data`. This is useful when we need to use the same component for different urls but using different data.
7070
* *isDefault*: boolean indicating wether this page should be the default, in case of non-existing URL. Think of it as the `otherwise` from Angular, so basically a 404 or the home page.
7171

72+
beforeUpdate is a middleware, this means you need to call the `next` function provided as the third argument, to continue routing. This allows to prevent a route based on some condition.
73+
7274
Vue is augmented with an additional method, `Vue.navigate(path, [trigger])`. [trigger] is a boolean (defaults to true) that will `pushState` if true, `replaceState` otherwise.
7375

7476
* The router will emit events on your $root VM: `routing:started`, `routing:beforeUpdate`, `routing:afterUpdate`.

component.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-route",
3-
"version": "1.3.3",
3+
"version": "1.4.0",
44
"repository": "ayamflow/vue-route",
55
"description": "Routing directive for Vue.js, inspired by ng-view.",
66
"main": "src/index.js",

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-route",
3-
"version": "1.3.3",
3+
"version": "1.4.0",
44
"description": "Routing directive for Vue.js, inspired by ng-view.",
55
"main": "src/index.js",
66
"scripts": {

src/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ module.exports = function(Vue) {
3333
path: null,
3434
componentId: null,
3535
params: null
36+
},
37+
38+
oldLocation: {
39+
regexp: null,
40+
path: null,
41+
componentId: null,
42+
params: null
3643
}
3744
}, component);
3845

src/routing.js

+78-30
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,26 @@ module.exports = function(Vue, page, utils) {
6868
if(this.options.debug) _.log('[v-route] addRoute', path, options);
6969

7070
var routeFn = function(context, next) {
71-
Vue.nextTick(function() {
71+
// Vue.nextTick(function() {
7272
this.onRoute(path, context, next);
73-
}, this);
73+
// }, this);
7474
};
7575

7676
// Add a relevant stack trace
7777
routeFn.displayName = 'routing ' + path;
7878

79-
page(path, _.bind(routeFn, this));
79+
// Middleware prop
80+
/*
81+
page(path, onRoute, beforeUpdate, updateRoute, afterUpdate);
82+
- onRoute -> updateLocation field
83+
- beforeUpdate -> emit event, call callbacks, if no callbacks -> next
84+
- updateRoute -> effectively applies the route, next
85+
- afterUpdate -> emit event, call callbacks
86+
*/
87+
88+
// page(path, _.bind(routeFn, this));
89+
90+
page(path, _.bind(routeFn, this), _.bind(this.beforeUpdate, this), _.bind(this.updateRoute, this));
8091

8192
if(options.isDefault) {
8293
this.defaultRoute = path;
@@ -103,27 +114,36 @@ module.exports = function(Vue, page, utils) {
103114
Get new route, componentId and update location context
104115
*/
105116
var route = this.routes[path],
106-
componentId = route.componentId,
107-
oldLocation = _.extend({}, this.location);
117+
componentId = route.componentId;
118+
119+
this.oldLocation.regexp = this.location.regexp;
120+
this.oldLocation.path = this.location.path;
121+
this.oldLocation.componentId = this.location.componentId;
122+
this.oldLocation.params = this.location.params;
108123

109124
this.location.regexp = path;
110125
this.location.path = context.path;
111126
this.location.componentId = componentId;
112127
this.location.params = context.params;
113128

114-
/*
115-
before applying the route, emit the event + execute custom callback
116-
*/
117-
this.callRouteHook('before', route.beforeUpdate, [this.location, oldLocation]);
118-
/*
119-
Update the current component
120-
*/
121-
this.update(componentId);
129+
next();
130+
},
122131

123-
/*
124-
after applying the route, emit the event + execute custom callback
125-
*/
126-
this.callRouteHook('after', route.afterUpdate, [this.location, oldLocation]);
132+
beforeUpdate: function(context, next) {
133+
this.callRouteHook('before', next);
134+
},
135+
136+
updateRoute: function() {
137+
/*
138+
Update the current component
139+
*/
140+
var componentId = this.routes[this.location.regexp].componentId;
141+
this.update(componentId);
142+
143+
/*
144+
after applying the route, emit the event + execute custom callback
145+
*/
146+
this.callRouteHook('after');
127147
},
128148

129149
/*
@@ -135,25 +155,53 @@ module.exports = function(Vue, page, utils) {
135155

136156
Vue.nextTick(function() {
137157
page(this.defaultRoute);
138-
}.bind(this));
158+
}, this);
139159
},
140160

141-
callRouteHook: function(when, method, params) {
142-
if(this.options.debug) _.log('[v-route] callRouteHook', when, method, params);
161+
callRouteHook: function(when, next) {
162+
if(this.options.debug) _.log('[v-route] callRouteHook', when, next);
143163

144-
if(method) {
145-
if(utils.toString.call(method) == '[object String]') {
146-
if(this.vm.$root[method]) {
147-
this.vm.$root[method].apply(this.vm.$root, params);
148-
}
149-
}
150-
else {
151-
method.apply(this.vm.$root, params);
164+
var route = this.routes[this.location.regexp],
165+
callback = route[when + 'Update'],
166+
$root = this.vm.$root,
167+
locations = [this.location, this.oldLocation],
168+
middleware;
169+
170+
if(callback) {
171+
if(utils.isFunction(callback)) {
172+
middleware = callback;
173+
}
174+
else if(utils.isString(callback)) {
175+
if($root[callback]) {
176+
middleware = $root[callback];
152177
}
178+
}
179+
}
180+
181+
_.nextTick(function() {
182+
this.callRouteEvents(when, locations);
183+
}, this);
184+
185+
/*
186+
If a middleware is declared, we call it and wait for the call to `next`
187+
*/
188+
if(middleware) {
189+
middleware.apply($root, utils.concat.call(locations, next));
190+
}
191+
192+
/*
193+
If no middleware is declared, we call `next` to continue the routing
194+
*/
195+
else if(next) {
196+
next();
153197
}
198+
},
199+
200+
callRouteEvents: function(when, locations) {
201+
var $root = this.vm.$root;
154202

155-
this.vm.$root[this.notifier].apply(this.vm.$root,
156-
utils.concat.call([], 'router:' + when + 'Update', params)
203+
$root[this.notifier].apply($root,
204+
utils.concat.call([], 'router:' + when + 'Update', locations)
157205
);
158206
}
159207
};

src/utils.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@
33
module.exports = {
44
hasOwnProp: Object.prototype.hasOwnProperty,
55
toString: Object.prototype.toString,
6-
concat: Array.prototype.concat
6+
concat: Array.prototype.concat,
7+
isString: function(str) {
8+
return this.toString.call(str).toLowerCase() == "[object string]";
9+
},
10+
isFunction: function(fn) {
11+
return this.toString.call(fn).toLowerCase() == "[object function]";
12+
}
713
};

0 commit comments

Comments
 (0)