Skip to content

Commit d247861

Browse files
committed
vue-router2
1 parent 0788456 commit d247861

File tree

7 files changed

+417
-0
lines changed

7 files changed

+417
-0
lines changed

packages/vue-router2/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.npm

packages/vue-router2/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
3+
## 0.2.0 - 2016/07/06
4+
5+
- (BREAKING CHANGE) You now have to create the router instance from the `Router` class in your client.
6+
- (BREAKING CHANGE) The `Router` class now extends the native vue-router class directly. `Router.lib` removed.
7+
- You can now call `Router.configure(router => {...})` to use vue-router before the router is created or started, regardless of the file load order.

packages/vue-router2/README.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Vue-router 2.x integration for Meteor
2+
3+
## Add routes in the blink of an eye.
4+
Routing for vue and meteor using [vue-router](https://github.com/vuejs/vue-router).
5+
6+
See the [example here](https://github.com/Akryum/meteor-vue2-example-routing).
7+
8+
## Installation
9+
10+
11+
meteor add akryum:vue-router2
12+
13+
## Usage
14+
15+
### Router options
16+
17+
First, let's create our router:
18+
19+
```javascript
20+
/* /client/client.js */
21+
22+
// Import the router
23+
import {Router, nativeScrollBehavior} from 'meteor/akryum:vue-router2';
24+
25+
// Create router instance
26+
const router = new Router({
27+
mode: 'history',
28+
scrollBehavior: nativeScrollBehavior,
29+
});
30+
```
31+
32+
When you create the router instance, you can pass `options` that allow you to customize the router behavior ([more info](http://router.vuejs.org/en/api/options.html)).
33+
34+
### Route definition
35+
36+
In your client, add some routes with the `Router.configure()` method (for more info about route definition, check the [vue-router documentation](http://router.vuejs.org/en/essentials/nested-routes.html)):
37+
38+
```javascript
39+
/* /client/routes.js */
40+
41+
// Import the router
42+
import {Router} from 'meteor/akryum:vue-router2';
43+
44+
// Components
45+
import Home from '/imports/ui/Home.vue';
46+
import Forum from '/imports/ui/Forum.vue';
47+
import Apollo from '/imports/ui/Apollo.vue';
48+
49+
Router.configure(router => {
50+
// Simple routes
51+
router.addRoutes([
52+
{
53+
path: '/',
54+
name: 'home',
55+
component: Home,
56+
},
57+
{
58+
path: '/forum',
59+
name: 'forum',
60+
component: Forum,
61+
},
62+
{
63+
path: '/apollo',
64+
name: 'apollo',
65+
component: Apollo,
66+
},
67+
]);
68+
});
69+
```
70+
71+
**Attention! The order of the routes matters during the route matching!***
72+
73+
The callbacks you pass to the `Router.configure()` calls will be called before the router is started, regardless of the file load order.
74+
75+
You can pass a second integer argument `priority`, that changes the order in which the callbacks are called to add routes. Callbacks with higher priority will be called before the others. The default priority is `0`.
76+
77+
#### Simple syntax
78+
79+
You can use an alternative special syntax in `.routes.js` files:
80+
81+
```javascript
82+
/* /client/main.routes.js */
83+
export default [
84+
{
85+
path: '/',
86+
name: 'home',
87+
component: '/imports/ui/Home.vue'
88+
},
89+
{
90+
path: '/forum',
91+
name: 'forum',
92+
component: '/imports/ui/Forum.vue'
93+
},
94+
{
95+
path: '/apollo',
96+
name: 'apollo',
97+
component: '/imports/ui/Apollo.vue'
98+
}
99+
];
100+
```
101+
102+
All the routes will be automatically added and the component's paths resolved.
103+
104+
### App menu
105+
106+
Use the `router-link` component to add dynamic links that take to different routes in your app ([more info](http://router.vuejs.org/en/api/router-link.html)):
107+
108+
```html
109+
<!-- /imports/ui/AppMenu.vue -->
110+
<template>
111+
<div class="app-menu">
112+
<router-link :to="{ name:'home', exact: true }">Home</router-link>
113+
<router-link :to="{ name:'forum' }">Forum</router-link>
114+
<router-link :to="{ name:'apollo' }">Apollo</router-link>
115+
</div>
116+
</template>
117+
118+
<style scoped lang="sass">
119+
@import ~imports/ui/colors.sass
120+
121+
.app-menu
122+
margin: 32px 0
123+
text-align: center
124+
125+
a
126+
display: inline-block
127+
padding: 6px
128+
margin: 0 6px
129+
border-radius: 3px
130+
&.v-link-active
131+
background: $app-color
132+
color: white
133+
</style>
134+
```
135+
136+
### App layout
137+
138+
Create a vue component with a `<router-view></router-view>` element, that will contain the route content ([more info](http://router.vuejs.org/en/api/router-view.html)):
139+
140+
```html
141+
<!-- /imports/ui/AppLayout.vue -->
142+
<template>
143+
<div class="app-layout">
144+
<!-- Menu -->
145+
<app-menu></app-menu>
146+
147+
<!-- Route content -->
148+
<router-view></router-view>
149+
</div>
150+
</template>
151+
152+
<script>
153+
import AppMenu from '/imports/ui/AppMenu.vue';
154+
155+
export default {
156+
components: {
157+
AppMenu
158+
}
159+
}
160+
</script>
161+
```
162+
163+
### Not found page
164+
165+
To add a 'not found' page, add a `*` route in your client code:
166+
167+
```javascript
168+
/* /client/routes.js */
169+
170+
// Import the router
171+
import {Router} from 'meteor/akryum:vue-router';
172+
173+
// Not found
174+
import NotFound from '/imports/ui/NotFound.vue';
175+
176+
Router.configure(router => {
177+
router.addRoute({
178+
path: '*',
179+
component: NotFound,
180+
});
181+
}, -1);
182+
```
183+
184+
*Note that we use a priority of `-1`, so this route is added last. If we don't do that, there is a chance that this route will be first and then will match immediatly: the user will be greeted by a 'not found' page everytime he loads the app!*
185+
186+
### Starting the router
187+
188+
Then import the routes and start the router in your client:
189+
190+
```javascript
191+
/* /client/client.js */
192+
193+
// App layout
194+
import AppLayout from '/imports/ui/AppLayout.vue';
195+
196+
// App start
197+
Meteor.startup(() => {
198+
// Start the router
199+
new Vue({
200+
router: router.start(),
201+
render: h => h(AppLayout),
202+
}).$mount('app');
203+
});
204+
205+
```
206+
207+
**If you put your routes files in the `/imports` folder, you need to import them manually.**
208+
209+
To start the router, use the `router.start()` method and pass the result to a Vue instance with the `router` option.
210+
211+
### Fast-render
212+
213+
You can use the [meteorhacks:fast-render](https://github.com/kadirahq/fast-render) package to inject the subscriptions data in the html. This greatly speeds up the initial render of your app if it depends on subscriptions.
214+
215+
First, install the fast-render package:
216+
217+
meteor add meteorhacks:fast-render
218+
219+
In your server, add fast-render routes:
220+
221+
```javascript
222+
FastRender.route('/forum', function(params) {
223+
this.subscribe('threads');
224+
});
225+
```
226+
227+
This will send the `threads` subscription data along side the html if the user open your app with the `yourapp/forum` url.
228+
229+
---
230+
231+
## Next steps
232+
233+
- [Example project](https://github.com/Akryum/meteor-vue2-example-routing)
234+
- [Integrate apollo](https://github.com/Akryum/vue-apollo)
235+
236+
---
237+
238+
LICENCE ISC - Created by Guillaume CHAU (@Akryum)

packages/vue-router2/client/client.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import Vue from 'vue';
2+
import VueRouter from 'vue-router';
3+
4+
Vue.use(VueRouter);
5+
6+
// scrollBehavior:
7+
// - only available in html5 history mode
8+
// - defaults to no scroll behavior
9+
// - return false to prevent scroll
10+
export const nativeScrollBehavior = (to, from, savedPosition) => {
11+
if (savedPosition) {
12+
// savedPosition is only available for popstate navigations.
13+
return savedPosition
14+
} else {
15+
const position = {}
16+
// new navigation.
17+
// scroll to anchor by returning the selector
18+
if (to.hash) {
19+
position.selector = to.hash
20+
}
21+
// check if any matched route config has meta that requires scrolling to top
22+
if (to.matched.some(m => m.meta.scrollToTop)) {
23+
// cords will be used if no selector is provided,
24+
// or if the selector didn't match any element.
25+
position.x = 0
26+
position.y = 0
27+
}
28+
// if the returned position is falsy or an empty object,
29+
// will retain current scroll position.
30+
return position
31+
}
32+
}
33+
34+
export class Router {
35+
// Vue-router constructor options
36+
constructor(options) {
37+
this.options = options;
38+
this.options.routes = options.routes || [];
39+
}
40+
41+
// The order of the routes matters
42+
addRoutes(array) {
43+
array.forEach(route => {
44+
this.addRoute(route);
45+
});
46+
}
47+
48+
addRoute(route) {
49+
this.options.routes.push(route);
50+
}
51+
52+
start() {
53+
// Callbacks
54+
Router._cbs.sort((a, b) => b.priority - a.priority).forEach(cb => cb(this));
55+
56+
// Real vue-router instance
57+
return this.router = new VueRouter(this.options);
58+
}
59+
60+
// Callbacks with higher priority will be called before
61+
static configure(cb, priority) {
62+
if(!Router._cbs) {
63+
Router._cbs = [];
64+
}
65+
cb.priority = priority || 0;
66+
Router._cbs.push(cb);
67+
}
68+
}

packages/vue-router2/npm.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"devDependencies": {
3+
"vue": "^2.0.0-rc.8",
4+
"vue-router": "^2.0.0-rc.5"
5+
}
6+
}

packages/vue-router2/package.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Package.describe({
2+
name: 'akryum:vue-router2',
3+
version: '0.0.1',
4+
summary: 'Easy vue routing for Meteor - vue-router 2.x',
5+
git: 'https://github.com/Akryum/meteor-vue-component',
6+
documentation: 'README.md'
7+
});
8+
9+
Package.registerBuildPlugin({
10+
name: "vue-router",
11+
use: [
12+
'ecmascript@0.4.4',
13+
'caching-compiler@1.0.5',
14+
'babel-compiler@6.8.0'
15+
],
16+
sources: [
17+
'plugin/plugin.js'
18+
]
19+
});
20+
21+
Package.onUse(function(api) {
22+
api.versionsFrom('1.3.3');
23+
api.use('isobuild:compiler-plugin@1.0.0');
24+
api.use('ecmascript');
25+
api.use('akryum:npm-check@0.0.2');
26+
api.mainModule('client/client.js', 'client');
27+
api.export(['Router', 'nativeScrollBehavior'], 'client');
28+
});

0 commit comments

Comments
 (0)