├── .editorconfig
├── .gitignore
├── README.md
├── component.json
├── package.json
├── src
├── index.js
├── overrides.js
├── routing.js
└── utils.js
└── test
├── common.js
└── keep-alive-data.js
/.editorconfig:
--------------------------------------------------------------------------------
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
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | npm-debug.log
4 | test/build.js
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | vue-route
2 | =======
3 |
4 | ## Vue-route is discontinued. Try the official [vue-router](https://github.com/vuejs/vue-router) instead.
5 |
6 | Routing directive for Vue.js, inspired by ng-view.
7 | Based on `v-component` thus benefits from `v-transition`, `keep-alive`, `wait-for`, `transition-mode`.
8 |
9 | Versions 1.5.0+ are made for **Vue.js v0.12+.**
10 | Use older versions for Vue.js v0.11.
11 |
12 | Allows you to declare your routes on the `$root` Vue object:
13 |
14 | ```js
15 | var root = new Vue({
16 | el: 'body',
17 |
18 | routes: {
19 | '/home': {
20 | componentId: 'fg-home',
21 | isDefault: true
22 | },
23 | '/items/:item': {
24 | componentId: 'fg-item',
25 | afterUpdate: 'updateHeader',
26 | data: {
27 | defaultColor: '#3453DD'
28 | }
29 | },
30 | options: {
31 | hashbang: true
32 | }
33 | }
34 | });
35 |
36 | ```
37 |
38 | With minimal markup:
39 |
40 | ```html
41 |
42 |
43 |
44 |
45 | ```
46 |
47 | `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.
48 |
49 | ## Get started
50 |
51 | **1.** Install with npm/component(1): `npm i vue-route --save` or `component install ayamflow/vue-route`.
52 |
53 | **2.** Require and install the plugin:
54 |
55 | ```js
56 | var Vue = require('vue'),
57 | route = require('vue-route');
58 |
59 | Vue.use(route); // BOOM
60 | ```
61 |
62 | **3.** Put the `` in your main template.
63 |
64 | **4.** Pass your routes to the `$root` VM of you app (see example above).
65 |
66 | **5.** Profit !
67 |
68 | ## Transition, keep-alive and other directives
69 | If you want to add custom transitions between your pages, it's recommended to put them on each page's component template. Putting anything on the `v-route` element itself will only be active if you change this element (for instance with a `v-if` directive).
70 | Following the example, that would be:
71 |
72 | ```js
73 | ...
// fg-home component
74 | ```
75 |
76 | ## Additional infos
77 |
78 | * Routes definition: when you pass your routes to the `$root`, you can pass several properties:
79 | * `componentId`: the Vue.component id for the associated template/VM.
80 | * `beforeUpdate`: a callback (method or name of method on the vm) to call before effectively changing to this routehtml.
81 | * `afterUpdate`: a callback (method or name of method on the vm) to call after effectively having changed to this route.
82 | * `data`: an object (or function returning 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.
83 | * `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.
84 |
85 | `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.
86 | For instance, you can `return` before `next` is called to cancel the route; usefull for an authentication page for instance.
87 | Another instance is to pause the app during loading and calling `next` when everything is loaded, thus resuming the flow.
88 |
89 | 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.
90 |
91 | * The router will emit events on your `$root` VM: `router:started`, `router:beforeUpdate`, `router:afterUpdate`.
92 |
93 | * You can pass a `options` hash to pass configuration to the router:
94 | * `hashbang`: boolean (defaults to false) to use `#!` urls. Note that your links shouldn't include hashbangs, the router handles this.
95 | * `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).
96 | * `base`: string (defaults to '/') to specify the base path.
97 | * `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`.
98 | * `debug`: boolean (defaults to false) to activate logging from the directive.
99 |
100 | ## Location context
101 |
102 | When the router emits an event, 2 parameters are passed: `location` and `oldLocation`. Like in Angular, it is an object containing some useful properties:
103 | * `regexp`: the route regexp, such as `/items/:item`.
104 | * `path`: the current path, such as `/items/razor/`.
105 | * `params`: a hash of the params from the route, here `{item: 'razor'}`.
106 | * `componentId`: the componentId associated to the current route.
107 |
108 | ## Route parameters
109 |
110 | 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'`.
111 |
112 | ## Subroutes
113 | Managing subviews with subroutes like `/route/:firstParam/:secondParam` is userland responsability; you should handle this with a `v-component` or programmatically.
114 |
115 | ## Compatibility note
116 | 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).
117 |
118 | ## Contributing
119 |
120 | * Fork & PR on **[dev](https://github.com/ayamflow/vue-route/tree/dev)** branch.
121 | * If possible, add tests to cover the changes.
122 | * Code style: 4 tabs, semicolons. Check the code if in doubt.
123 |
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-route",
3 | "version": "1.5.1",
4 | "repository": "ayamflow/vue-route",
5 | "description": "Routing directive for Vue.js, inspired by ng-view.",
6 | "main": "src/index.js",
7 | "scripts": [
8 | "src/index.js",
9 | "src/overrides.js",
10 | "src/routing.js",
11 | "src/utils.js"
12 | ],
13 | "keywords": [
14 | "vue",
15 | "route",
16 | "router",
17 | "page",
18 | "transition"
19 | ],
20 | "author": "= <=>",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/ayamflow/vue-route/issues"
24 | },
25 | "dependencies": {
26 | "visionmedia/page.js": "^1.5.0"
27 | },
28 | "development": {
29 | "dependencies": {
30 | "yyx990803/vue": "^0.11.3",
31 | "substack/tape": "^3.0.2"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-route",
3 | "version": "1.5.1",
4 | "description": "Routing directive for Vue.js, inspired by ng-view.",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "test": "./node_modules/.bin/prova ./test/**/*.js -b -l phantom -q",
8 | "test-browser": "./node_modules/.bin/prova ./test/**/*.js -b -l chrome"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/ayamflow/vue-route"
13 | },
14 | "keywords": [
15 | "vue",
16 | "route",
17 | "router",
18 | "page",
19 | "transition"
20 | ],
21 | "author": "= <=>",
22 | "license": "MIT",
23 | "bugs": {
24 | "url": "https://github.com/ayamflow/vue-route/issues"
25 | },
26 | "devDependencies": {
27 | "prova": "^2.1.2",
28 | "vue": "^0.12.9"
29 | },
30 | "dependencies": {
31 | "page": "^1.5.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./utils'),
4 | page = require('page');
5 |
6 | module.exports = function(Vue) {
7 | var component = Vue.directive('_component'),
8 | overrides = require('./overrides')(Vue),
9 | routing = require('./routing')(Vue, page, utils),
10 | _ = Vue.util;
11 |
12 | var routeDefinition = _.extend({
13 | isLiteral: true,
14 |
15 | // Vue event method, $emit or $broadcast
16 | notifier: null,
17 |
18 | defaultRoute: '/',
19 |
20 | // Reference to $root.$options.routes
21 | routes: {},
22 |
23 | // Options to be passed to the routing library
24 | options: {
25 | base: '/',
26 | hashbang: false,
27 | click: true
28 | },
29 |
30 | // Location context
31 | location: {
32 | regexp: null,
33 | path: null,
34 | componentId: null,
35 | params: null
36 | },
37 |
38 | oldLocation: {
39 | regexp: null,
40 | path: null,
41 | componentId: null,
42 | params: null
43 | }
44 | }, component);
45 |
46 | // Extend the routing-related methods
47 | _.extend(routeDefinition, routing);
48 |
49 | // override some of components methods
50 | _.extend(routeDefinition, overrides);
51 |
52 | Vue.directive('route', routeDefinition);
53 | };
54 |
--------------------------------------------------------------------------------
/src/overrides.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Overrides for (some of) v-component methods
5 | */
6 |
7 | var utils = require('./utils');
8 |
9 | module.exports = function(Vue) {
10 | var component = Vue.directive('_component'),
11 | _ = Vue.util,
12 | parsers = Vue.parsers;
13 |
14 | return {
15 | bind: function() {
16 | // Force dynamic directive
17 | this._isDynamicLiteral = true;
18 | component.bind.call(this);
19 | this.init();
20 | },
21 |
22 | /*
23 | This one is copied/pasted from the source
24 | except the routeParams part (no way to override it cleanly :/)
25 | */
26 | build: function(data) {
27 | var routeData = this.routes[this.location.regexp].data;
28 |
29 | // The 'data' function should use the passed one, if any,
30 | // and get merged with any data passed to the plugin for this route,
31 | // as well as the router params (GET params)
32 | var compData = _.extend({}, data);
33 | compData = _.extend(compData, (utils.isFunction(routeData) ? routeData() : routeData) || {});
34 | compData = _.extend(compData, {
35 | $routeParams: this.location.params
36 | });
37 |
38 | if(this.keepAlive) {
39 | var cached = this.cache[this.componentID];
40 | if(cached) {
41 | _.extend(cached.$data, compData);
42 | return cached;
43 | }
44 | }
45 |
46 | if(this.Component) {
47 | var parent = this._host || this.vm;
48 | var el = parsers.template.clone(this.el);
49 | var child = parent.$addChild({
50 | el: el,
51 | data: function() {
52 | return compData;
53 | },
54 | template: this.template,
55 | // if no inline-template, then the compiled
56 | // linker can be cached for better performance.
57 | _linkerCachable: !this.template,
58 | _asComponent: true,
59 | _isRouterView: this._isRouterView,
60 | _context: this.vm
61 | }, this.Component);
62 |
63 | if(this.keepAlive) {
64 | this.cache[this.componentID] = child;
65 | }
66 |
67 | return child;
68 | }
69 | }
70 | };
71 | };
72 |
--------------------------------------------------------------------------------
/src/routing.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | Routing API
5 | Methods for handling the route change
6 | and trigger the directive update
7 | */
8 |
9 | module.exports = function(Vue, page, utils) {
10 | var _ = Vue.util;
11 |
12 | /*
13 | Allow to manually navigate to a path.
14 | Useful if you passed the `click: false` option.
15 | */
16 | Vue.navigate = function(path, trigger) {
17 | page.show(path, null, trigger !== false);
18 | };
19 |
20 | return {
21 | init: function() {
22 | /*
23 | Link the routes declaration
24 | */
25 | this.routes = this.vm.$root.$options.routes;
26 | if(!this.routes) {
27 | _.warn('v-route needs the $root to be passed a "routes" option hash.');
28 | }
29 |
30 | /*
31 | Options for v-route & page (base, hashbang, debug...)
32 | */
33 | this.options = this.routes.options || {};
34 |
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 |
43 | /*
44 | If options.broadcast, uses $broadcast for routing events, else uses $emit
45 | */
46 | this.notifier = !!this.options.broadcast ? '$broadcast' : '$emit';
47 |
48 | /*
49 | Register all the routes
50 | */
51 | for(var route in this.routes) {
52 | // Ignore options
53 | if(route[0] === '/') {
54 | if(utils.hasOwnProp.call(this.routes, route)) {
55 | this.addRoute(route, this.routes[route]);
56 | }
57 | }
58 | }
59 |
60 | /*
61 | Bind default route
62 | */
63 | page('*', _.bind(this.onDefaultRoute, this));
64 |
65 | /*
66 | Start the routing
67 | */
68 | this.start();
69 | },
70 |
71 | /*
72 | Registers the route with the specified path/pattern (express-like regexp)
73 | route: infos as {id: "route-id", path: "/route"} or {id: "route-id", path: "/route/:id"}
74 | */
75 | addRoute: function(path, options) {
76 | if(this.options.debug) _.log('[v-route] addRoute', path, options);
77 |
78 | var routeFn = function(context, next) {
79 | // Vue.nextTick(function() {
80 | this.onRoute(path, context, next);
81 | // }, this);
82 | };
83 |
84 | // Add a relevant stack trace
85 | routeFn.displayName = 'routing ' + path;
86 |
87 | // Middleware prop
88 | /*
89 | page(path, onRoute, beforeUpdate, updateRoute, afterUpdate);
90 | - onRoute -> updateLocation field
91 | - beforeUpdate -> emit event, call callbacks, if no callbacks -> next
92 | - updateRoute -> effectively applies the route, next
93 | - afterUpdate -> emit event, call callbacks
94 | */
95 |
96 | // page(path, _.bind(routeFn, this));
97 |
98 | page(path, _.bind(routeFn, this), _.bind(this.beforeUpdate, this), _.bind(this.updateRoute, this));
99 |
100 | if(options.isDefault) {
101 | this.defaultRoute = path;
102 | }
103 | },
104 |
105 | /*
106 | Starts the router.
107 | */
108 | start: function() {
109 | if(this.options.debug) _.log('[v-route] start');
110 | page.start(this.options);
111 | this.vm.$root[this.notifier]('router:started');
112 | },
113 |
114 | /*
115 | Internal method.
116 | Updates the context and emit the `router:update` event.
117 | */
118 | onRoute: function(path, context, next) {
119 | if(this.options.debug) _.log('[v-route] onRoute', path, context);
120 |
121 | /*
122 | Get new route, componentId and update location context
123 | */
124 | var route = this.routes[path],
125 | componentId = route.componentId;
126 |
127 | this.oldLocation = _.extend({}, this.location);
128 | this.location = {
129 | regexp: path,
130 | path: context.path,
131 | componentId: componentId,
132 | params: context.params
133 | };
134 |
135 | next();
136 | },
137 |
138 | beforeUpdate: function(context, next) {
139 | this.callRouteHook('before', next);
140 | },
141 |
142 | updateRoute: function() {
143 | /*
144 | Update the current component
145 | */
146 | var componentId = this.routes[this.location.regexp].componentId;
147 | this.update(componentId);
148 |
149 | /*
150 | after applying the route, emit the event + execute custom callback
151 | */
152 | this.callRouteHook('after');
153 | },
154 |
155 | /*
156 | Called when the requested route does not exists
157 | Redirects to proper default route
158 | */
159 | onDefaultRoute: function(context) {
160 | if(this.options.debug) _.log('[v-route] onDefaultRoute', context);
161 |
162 | Vue.nextTick(function() {
163 | page(this.defaultRoute);
164 | }, this);
165 | },
166 |
167 | callRouteHook: function(when, next) {
168 | if(this.options.debug) _.log('[v-route] callRouteHook', when, next);
169 |
170 | var route = this.routes[this.location.regexp],
171 | callback = route[when + 'Update'],
172 | $root = this.vm.$root,
173 | locations = [this.location, this.oldLocation],
174 | middleware;
175 |
176 | if(callback) {
177 | if(utils.isFunction(callback)) {
178 | middleware = callback;
179 | }
180 | else if(utils.isString(callback)) {
181 | if($root[callback]) {
182 | middleware = $root[callback];
183 | }
184 | }
185 | }
186 |
187 | _.nextTick(function() {
188 | this.callRouteEvents(when, locations);
189 | }, this);
190 |
191 | /*
192 | If a middleware is declared, we call it and wait for the call to `next`
193 | */
194 | if(middleware) {
195 | middleware.apply($root, utils.concat.call(locations, next));
196 | }
197 |
198 | /*
199 | If no middleware is declared, we call `next` to continue the routing
200 | */
201 | else if(next) {
202 | next();
203 | }
204 | },
205 |
206 | callRouteEvents: function(when, locations) {
207 | var $root = this.vm.$root;
208 |
209 | $root[this.notifier].apply($root,
210 | utils.concat.call([], 'router:' + when + 'Update', locations)
211 | );
212 | }
213 | };
214 | };
215 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | hasOwnProp: Object.prototype.hasOwnProperty,
5 | toString: Object.prototype.toString,
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 | }
13 | };
--------------------------------------------------------------------------------
/test/common.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | General purpose tests
5 | */
6 |
7 | var test = require('prova'),
8 | Vue = require('vue'),
9 | page = require('page'),
10 | route = require('../src/index.js');
11 |
12 | var has = Object.prototype.hasOwnProperty;
13 |
14 | // Insert pushtate markup
15 | var tempDiv = document.createElement('div');
16 | tempDiv.innerHTML = '';
17 | var $head = document.getElementsByTagName('head')[0];
18 | $head.appendChild(tempDiv.firstChild);
19 | $head.appendChild(tempDiv.firstChild);
20 | // Insert v-route directive
21 | tempDiv.innerHTML = '';
22 | document.body.appendChild(tempDiv.firstChild);
23 |
24 | /*
25 | Test setup
26 | */
27 | Vue.use(route);
28 |
29 | Vue.component('page-1', {
30 | template: ''
31 | });
32 |
33 | Vue.component('page-2', {
34 | template: ''
35 | });
36 |
37 | Vue.component('page-3', {
38 | template: '',
39 | created: function() {
40 | this.$root.$emit('page3', this.$data.$routeParams);
41 | }
42 | });
43 |
44 | var beforeCalled = false,
45 | afterCalled = false,
46 | routes = {
47 | '/page1': {
48 | componentId: 'page-1',
49 | isDefault: true
50 | },
51 | '/page2': {
52 | componentId: 'page-2',
53 | beforeUpdate: before,
54 | afterUpdate: 'after'
55 | },
56 | '/page3/:foo': {
57 | componentId: 'page-3'
58 | },
59 | '/with-data': {
60 | componentId: 'page-1',
61 | data: {
62 | bar: 'baz'
63 | }
64 | },
65 | options: {
66 | hashbang: true,
67 | base: '/lol',
68 | click: false,
69 | debug: true
70 | }
71 | };
72 |
73 | function before(location, oldLocation, next) {
74 | beforeCalled = true;
75 | next();
76 | }
77 |
78 | var root = window.root = new Vue({
79 | el: 'body',
80 |
81 | routes: routes,
82 |
83 | methods: {
84 | after: function() {
85 | afterCalled = true;
86 | }
87 | }
88 | });
89 |
90 | test('addRoute', function(assert) {
91 | for(var route in routes) {
92 | if(has.call(routes, route)) {
93 | assert.equal(routes[route], root.$options.routes[route], 'route ' + route + ' should be set.');
94 | }
95 | }
96 |
97 | assert.end();
98 | });
99 |
100 | test('before/after callbacks', function(assert) {
101 | assert.plan(2);
102 |
103 | beforeCalled = false;
104 | afterCalled = false;
105 |
106 | Vue.navigate('/page2');
107 |
108 | Vue.nextTick(function() {
109 | assert.ok(beforeCalled, 'before callback was called as a method.');
110 | assert.ok(afterCalled, 'after callback was called as a string (method on root vm).');
111 | });
112 | });
113 |
114 | test('router events', function(assert) {
115 | assert.plan(2);
116 |
117 | root.$on('router:beforeUpdate', function() {
118 | assert.pass('router:beforeUpdate event has been called.');
119 | });
120 |
121 | root.$on('router:afterUpdate', function() {
122 | assert.pass('router:afterUpdate event has been called.');
123 | });
124 |
125 | Vue.navigate('/page1');
126 | });
127 |
128 |
129 | test('location context update', function(assert) {
130 | assert.plan(1);
131 | root.$off();
132 |
133 | root.$on('router:afterUpdate', function(location, oldLocation) {
134 | assert.notEqual(location.path, oldLocation.path, 'location and oldLocation should be different.');
135 | });
136 |
137 | Vue.navigate('/page2');
138 | });
139 |
140 | test('route params', function(assert) {
141 | assert.plan(1);
142 | root.$off();
143 |
144 | var foo = 'thing';
145 |
146 | root.$on('page3', function(params) {
147 | assert.equal(params.foo, foo, 'The route parameter should have been set.');
148 | });
149 |
150 | Vue.navigate('/page3/' + foo);
151 | });
152 |
153 | test('hashbang', function(assert) {
154 | assert.plan(1);
155 |
156 | assert.equal('#!', window.location.hash.slice(0, 2), 'The URL has an hashbang');
157 | });
158 |
159 | test('onDefaultRoute', function(assert) {
160 | assert.plan(1);
161 |
162 | // Navigate to random URL
163 | Vue.navigate('/' + (Math.random() * 10000).toString(36));
164 |
165 | Vue.nextTick(function() {
166 | assert.equal(location.hash.replace('#!', ''), '/page1', 'Should get back to the default route.');
167 | });
168 | });
169 |
170 | test('data', function(assert) {
171 | assert.plan(1);
172 | root.$off();
173 |
174 | Vue.navigate('/with-data');
175 | Vue.nextTick(function() {
176 | assert.equal(root.$children[0].bar, 'baz', 'Should have a data');
177 | });
178 | });
179 |
--------------------------------------------------------------------------------
/test/keep-alive-data.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('prova'),
4 | Vue = require('vue'),
5 | page = require('page'),
6 | route = require('../src/index.js');
7 |
8 | var tempDiv = document.createElement('div');
9 | tempDiv.innerHTML = '';
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: '',
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: '',
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 | });
69 | */
70 |
--------------------------------------------------------------------------------