Skip to content

Commit 74bfa1e

Browse files
committed
Merge branch 'dev'
2 parents a21012a + aa8af40 commit 74bfa1e

File tree

9 files changed

+237
-45
lines changed

9 files changed

+237
-45
lines changed

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ var root = new Vue({
1515
componentId: 'fg-home',
1616
isDefault: true
1717
},
18-
'/work/:work': {
19-
componentId: 'fg-work',
18+
'/items/:item': {
19+
componentId: 'fg-item',
2020
afterUpdate: 'updateHeader',
2121
data: {
2222
defaultColor: '#3453DD'
@@ -85,11 +85,18 @@ Vue is augmented with an additional method, `Vue.navigate(path, [trigger])`. [tr
8585
## Location context
8686

8787
When the router emits an event, 2 parameters are passed: `location` and `oldLocation`. Like in Angular, it is an object containing some useful properties:
88-
* `regexp`: the route regexp, such as `/items/:itemId`.
88+
* `regexp`: the route regexp, such as `/items/:item`.
8989
* `path`: the current path, such as `/items/razor/`.
9090
* `params`: a hash of the params from the route, here `{item: 'razor'}`.
9191
* `componentId`: the componentId associated to the current route.
9292

93+
## Route parameters
94+
95+
Each component used by `v-route` will have its `$data` extended with the `location.params` array (see above). That means that on the route `/items/razor`, `this.$data.$routeParams.item == 'razor'`.
96+
97+
## Compatibility note
98+
vue-route supports the same browsers as Vue; however to make it properly work on IE9 you need to add the [HTML5-history-API polyfill](https://github.com/devote/HTML5-History-API).
99+
93100
## Contributing
94101

95102
* Fork & PR on **[dev](https://github.com/ayamflow/vue-route/tree/dev)** branch.

README.md.orig

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
vue-route
2+
=======
3+
4+
Routing directive for Vue.js **(v0.11)**, inspired by ng-view.
5+
Based on `v-component` thus benefits from `v-transition`, `keep-alive`, `wait-for`, `transition-mode`.
6+
7+
Allows you to declare your routes on the `$root` Vue object:
8+
9+
```js
10+
var root = new Vue({
11+
el: 'body',
12+
13+
routes: {
14+
'/home': {
15+
componentId: 'fg-home',
16+
isDefault: true
17+
},
18+
'/work/:work': {
19+
componentId: 'fg-work',
20+
afterUpdate: 'updateHeader',
21+
data: {
22+
defaultColor: '#3453DD'
23+
}
24+
},
25+
options: {
26+
hashbang: true
27+
}
28+
}
29+
});
30+
31+
```
32+
33+
With minimal markup:
34+
35+
```html
36+
<body>
37+
<div v-route></div>
38+
</body>
39+
40+
```
41+
42+
`vue-route` extends the `v-component` directive by @yyx990803 (on the [vuejs repo](https://github.com/yyx990803/vue/tree/master/src/directives/component.js)). Buy him a coffee if you can.
43+
44+
## Get started
45+
46+
**1.** Install with npm/component(1): `npm i vue-route --save` or `component install ayamflow/vue-route`.
47+
48+
**2.** Require and install the plugin:
49+
50+
```js
51+
var Vue = require('vue'),
52+
route = require('vue-route');
53+
54+
Vue.use(route); // BOOM
55+
```
56+
57+
**3.** Put the `<div v-route></div>` in your main template.
58+
59+
**4.** Pass your routes to the `$root` VM of you app (see example above).
60+
61+
**5.** Profit !
62+
63+
## Additional infos
64+
65+
* Routes definition: when you pass your routes to the `$root`, you can pass several properties:
66+
* `componentId`: the Vue.component id for the associated template/VM.
67+
* `beforeUpdate`: a callback (method or name of method on the vm) to call before effectively changing to this routehtml.
68+
* `afterUpdate`: a callback (method or name of method on the vm) to call after effectively having changed to this route.
69+
* `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.
70+
* `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.
71+
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+
74+
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.
75+
76+
* The router will emit events on your `$root` VM: `router:started`, `router:beforeUpdate`, `router:afterUpdate`.
77+
78+
* You can pass a `options` hash to pass configuration to the router:
79+
<<<<<<< HEAD
80+
* `hashbang`: boolean (defaults to false) to use `#!` urls. Note that your links shouldn't include hashbangs, the router handles this.
81+
* `click`: boolean (defaults to true) to automatically bind all click to the router. Not that if `false`, you will need to explicitly call `Vue.navigate` method).
82+
* `base`: string (defaults to '/') to specify the base path.
83+
* `broadcast`: boolean (defaults to false) if true the events will be emitted using the $root `$broadcast` method, so all child VMs will receive the event until a handler `return false;`. If false, it uses `$emit`.
84+
* `debug`: boolean (defaults to false) to activate logging from the directive.
85+
=======
86+
* `hashbang` boolean (defaults to false) to use `#!` urls. Note that your links shouldn't include hashbangs, the router handles this.
87+
* `click` boolean (defaults to true) to automatically bind all click to the router. Not that if `false`, you will need to explicitly call `Vue.navigate` method)
88+
* `base` string (defaults to '/') to specify the base path
89+
* `broadcast` boolean (defaults to false) if true the events will be emitted using the $root `$broadcast` method, so all child VMs will receive the event until a handler `return false;`. If false, it uses `$emit`.
90+
* `debug` boolean (defaults to false) to activate logging from the directive.
91+
>>>>>>> Add notice regarding URL and hashbangs as seen in #15.
92+
93+
## Location context
94+
95+
When the router emits an event, 2 parameters are passed: `location` and `oldLocation`. Like in Angular, it is an object containing some useful properties:
96+
* `regexp`: the route regexp, such as `/items/:itemId`.
97+
* `path`: the current path, such as `/items/razor/`.
98+
* `params`: a hash of the params from the route, here `{item: 'razor'}`.
99+
* `componentId`: the componentId associated to the current route.
100+
101+
## Contributing
102+
103+
* Fork & PR on **[dev](https://github.com/ayamflow/vue-route/tree/dev)** branch.
104+
* If possible, add tests to cover the changes.
105+
* Code style: 4 tabs, semicolons. Check the code if in doubt.

component.json

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

package.json

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

src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module.exports = function(Vue) {
2727
click: true
2828
},
2929

30-
// Location context, init (event with null) to avoid mutating it later (fast object)
30+
// Location context
3131
location: {
3232
regexp: null,
3333
path: null,
@@ -50,4 +50,4 @@ module.exports = function(Vue) {
5050
_.extend(routeDefinition, overrides);
5151

5252
Vue.directive('route', routeDefinition);
53-
};
53+
};

src/overrides.js

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,46 @@ module.exports = function(Vue) {
1818
},
1919

2020
resolveCtor: function(id) {
21-
if(!id.length) return;
22-
component.resolveCtor.call(this, id);
21+
if(!id.length) return;
22+
component.resolveCtor.call(this, id);
2323
},
2424

2525
/*
2626
This one is copied/pasted from the source
2727
except the routeParams part (no way to override it cleanly :/)
2828
*/
2929
build: function() {
30-
if (this.keepAlive) {
31-
var cached = this.cache[this.ctorId];
32-
if (cached) {
33-
return cached;
30+
var data = _.extend({}, this.routes[this.location.regexp].data || {});
31+
data = _.extend(data, {
32+
$routeParams: this.location.params
33+
});
34+
35+
if(this.keepAlive) {
36+
var cached = this.cache[this.ctorId];
37+
if(cached) {
38+
_.extend(cached.$data, data);
39+
return cached;
40+
}
3441
}
35-
}
36-
37-
var vm = this.vm;
38-
var el = parsers.template.clone(this.el);
39-
var data = _.extend(this.routes[this.location.regexp].data || {}, {
40-
$routeParams: this.location.params
41-
});
42-
43-
if (this.Ctor) {
44-
var child = vm.$addChild({
45-
el: el,
46-
_asComponent: true,
47-
data: function() {
48-
return data;
49-
}
50-
}, this.Ctor);
51-
if (this.keepAlive) {
52-
this.cache[this.ctorId] = child;
42+
43+
var vm = this.vm;
44+
var el = parsers.template.clone(this.el);
45+
46+
if(this.Ctor) {
47+
var child = vm.$addChild({
48+
el: el,
49+
_asComponent: true,
50+
data: function() {
51+
return data;
52+
}
53+
}, this.Ctor);
54+
55+
if(this.keepAlive) {
56+
this.cache[this.ctorId] = child;
57+
}
58+
59+
return child;
5360
}
54-
return child;
55-
}
5661
}
5762
};
58-
};
63+
};

src/routing.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ module.exports = function(Vue, page, utils) {
3232
*/
3333
this.options = this.routes.options || {};
3434

35+
/*
36+
Use page.base to set the URL base
37+
TODO tests
38+
*/
39+
if(this.options.base) {
40+
page.base(this.options.base);
41+
}
42+
3543
/*
3644
If options.broadcast, uses $broadcast for routing events, else uses $emit
3745
*/
@@ -116,15 +124,13 @@ module.exports = function(Vue, page, utils) {
116124
var route = this.routes[path],
117125
componentId = route.componentId;
118126

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;
123-
124-
this.location.regexp = path;
125-
this.location.path = context.path;
126-
this.location.componentId = componentId;
127-
this.location.params = context.params;
127+
this.oldLocation = _.extend({}, this.location);
128+
this.location = {
129+
regexp: path,
130+
path: context.path,
131+
componentId: componentId,
132+
params: context.params
133+
};
128134

129135
next();
130136
},
@@ -205,4 +211,4 @@ module.exports = function(Vue, page, utils) {
205211
);
206212
}
207213
};
208-
};
214+
};

test/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ if(!Function.prototype.bind) {
55
Function.prototype.bind = require("function-bind");
66
}
77

8-
require('./common.js');
8+
require('./common.js');
9+
// require('./keep-alive-data.js');

test/keep-alive-data.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
var test = require('tape'),
4+
Vue = require('vue'),
5+
page = require('page'),
6+
route = require('../src/index.js');
7+
8+
var tempDiv = document.createElement('div');
9+
tempDiv.innerHTML = '<div keep-alive v-route></div>';
10+
document.body.appendChild(tempDiv.firstChild);
11+
12+
var routes = {
13+
'/page1': {
14+
componentId: 'page-1',
15+
data: {
16+
isPage1: true
17+
},
18+
isDefault: true
19+
},
20+
'/page2/:page': {
21+
componentId: 'page-2',
22+
data: {
23+
isPage1: 'nope',
24+
isPage2: true
25+
}
26+
}
27+
};
28+
29+
Vue.use(route);
30+
31+
Vue.component('page-1', {
32+
template: '<div class="page1"></div>',
33+
ready: function() {
34+
// console.log('page-1', this.$data.$routeParams.page);
35+
// console.log('page-1', routes['/page2/:page'].data, this.$data);
36+
}
37+
});
38+
39+
Vue.component('page-2', {
40+
template: '<h2 keep-alive class="page2"></h2>',
41+
attached: function() {
42+
console.log('page-2', this.$data.$routeParams.page);
43+
// console.log('page-2', routes['/page2/:page'].data, this.$data);
44+
}
45+
});
46+
47+
var root = new Vue({
48+
el: 'body',
49+
routes: routes
50+
});
51+
52+
test('data', function(assert) {
53+
setTimeout(function() {
54+
Vue.navigate('/page2/test');
55+
setTimeout(function() {
56+
Vue.navigate('/page1');
57+
setTimeout(function() {
58+
Vue.navigate('/page2/otherParam');
59+
setTimeout(function() {
60+
Vue.navigate('/page1');
61+
setTimeout(function() {
62+
Vue.navigate('/page2/andAnother');
63+
}, 800);
64+
}, 800);
65+
}, 800);
66+
}, 800);
67+
}, 800);
68+
});

0 commit comments

Comments
 (0)