Vue Router的配置
1.beforeEnter
function requireAuth (route, redirect, next) { if (!auth.loggedIn()) { redirect({ path: '/login', query: { redirect: route.fullPath } }) } else { next() } } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/about', component: About }, { path: '/dashboard', component: Dashboard, beforeEnter: requireAuth }, { path: '/login', component: Login }, { path: '/logout', beforeEnter (route, redirect) { auth.logout() redirect('/') } } ] })
2.LazyLoading
// For single component, we can use the AMD shorthand // require(['dep'], dep => { ... }) const Foo = resolve => require(['./Foo.vue'], resolve) // If using Webpack 2, you can also do: // const Foo = () => System.import('./Foo.vue') // If you want to group a number of components that belong to the same // nested route in the same async chunk, you will need to use // require.ensure. The 3rd argument is the chunk name they belong to - // modules that belong to the same chunk should use the same chunk name. const Bar = r => require.ensure([], () => r(require('./Bar.vue')), '/bar') const Baz = r => require.ensure([], () => r(require('./Baz.vue')), '/bar') const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: Home }, // Just use them normally in the route config { path: '/foo', component: Foo }, // Bar and Baz belong to the same root route // and grouped in the same async chunk. { path: '/bar', component: Bar, children: [ { path: 'baz', component: Baz } ] } ] })
3.定義多個Component
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } const Baz = { template: '<div>baz</div>' } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', // a single route can define multiple named components // which will be rendered into <router-view>s with corresponding names. components: { default: Foo, a: Bar, b: Baz } }, { path: '/other', components: { default: Baz, a: Bar, b: Foo } } ] }) new Vue({ router, template: ` <div id="app"> <h1>Named Views</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/other">/other</router-link></li> </ul> <router-view class="view one"></router-view> <router-view class="view two" name="a"></router-view> <router-view class="view three" name="b"></router-view> </div> ` }).$mount('#app')
4.導航守護
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const Home = { template: '<div>home</div>' } const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } /** * Signatre of all route guards: * @param {Route} route * @param {Function} redirect - redirect to another route * @param {Function} next - confirm the route */ function guardRoute (route, redirect, next) { if (window.confirm(`Navigate to ${route.path}?`)) { next() } else if (window.confirm(`Redirect to /baz?`)) { redirect('/baz') } } // Baz implements an in-component beforeRouteLeave hook const Baz = { data () { return { saved: false } }, template: ` <div> <p>baz ({{ saved ? 'saved' : 'not saved' }})<p> <button @click="saved = true">save</button> </div> `, beforeRouteLeave (route, redirect, next) { if (this.saved || window.confirm('Not saved, are you sure you want to navigate away?')) { next() } } } // Baz implements an in-component beforeRouteEnter hook const Qux = { data () { return { msg: null } }, template: `<div>{{ msg }}</div>`, beforeRouteEnter (route, redirect, next) { // Note that enter hooks do not have access to `this` // because it is called before the component is even created. // However, we can provide a callback to `next` which will // receive the vm instance when the route has been confirmed. // // simulate an async data fetch. // this pattern is useful when you want to stay at current route // and only switch after the data has been fetched. setTimeout(() => { next(vm => { vm.msg = 'Qux' }) }, 300) } } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: Home }, // inline guard { path: '/foo', component: Foo, beforeEnter: guardRoute }, // using meta properties on the route config // and check them in a global before hook { path: '/bar', component: Bar, meta: { needGuard: true }}, // Baz implements an in-component beforeRouteLeave hook { path: '/baz', component: Baz }, // Qux implements an in-component beforeRouteEnter hook { path: '/qux', component: Qux }, // in-component beforeRouteEnter hook for async components { path: '/qux-async', component: resolve => { setTimeout(() => { resolve(Qux) }, 0) } } ] }) router.beforeEach((route, redirect, next) => { if (route.matched.some(m => m.meta.needGuard)) { guardRoute(route, redirect, next) } else { next() } }) new Vue({ router, template: ` <div id="app"> <h1>Navigation Guards</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/foo">/foo</router-link></li> <li><router-link to="/bar">/bar</router-link></li> <li><router-link to="/baz">/baz</router-link></li> <li><router-link to="/qux">/qux</router-link></li> <li><router-link to="/qux-async">/qux-async</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')
5.Redirect
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const Home = { template: '<router-view></router-view>' } const Default = { template: '<div>default</div>' } const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } const Baz = { template: '<div>baz</div>' } const WithParams = { template: '<div>{{ $route.params.id }}</div>' } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: Home, children: [ { path: '', component: Default }, { path: 'foo', component: Foo }, { path: 'bar', component: Bar }, { path: 'baz', name: 'baz', component: Baz }, { path: 'with-params/:id', component: WithParams }, // relative redirect to a sibling route { path: 'relative-redirect', redirect: 'foo' } ] }, // absolute redirect { path: '/absolute-redirect', redirect: '/bar' }, // dynamic redirect, note that the target route `to` is available for the redirect function { path: '/dynamic-redirect/:id?', redirect: to => { const { hash, params, query } = to if (query.to === 'foo') { return { path: '/foo', query: null } } if (hash === '#baz') { return { name: 'baz', hash: '' } } if (params.id) { return '/with-params/:id' } else { return '/bar' } } }, // named redirect { path: '/named-redirect', redirect: { name: 'baz' }}, // redirect with params { path: '/redirect-with-params/:id', redirect: '/with-params/:id' }, // catch all redirect { path: '*', redirect: '/' } ] }) new Vue({ router, template: ` <div id="app"> <h1>Redirect</h1> <ul> <li><router-link to="/relative-redirect"> /relative-redirect (redirects to /foo) </router-link></li> <li><router-link to="/relative-redirect?foo=bar"> /relative-redirect?foo=bar (redirects to /foo?foo=bar) </router-link></li> <li><router-link to="/absolute-redirect"> /absolute-redirect (redirects to /bar) </router-link></li> <li><router-link to="/dynamic-redirect"> /dynamic-redirect (redirects to /bar) </router-link></li> <li><router-link to="/dynamic-redirect/123"> /dynamic-redirect/123 (redirects to /with-params/123) </router-link></li> <li><router-link to="/dynamic-redirect?to=foo"> /dynamic-redirect?to=foo (redirects to /foo) </router-link></li> <li><router-link to="/dynamic-redirect#baz"> /dynamic-redirect#baz (redirects to /baz) </router-link></li> <li><router-link to="/named-redirect"> /named-redirect (redirects to /baz) </router-link></li> <li><router-link to="/redirect-with-params/123"> /redirect-with-params/123 (redirects to /with-params/123) </router-link></li> <li><router-link to="/not-found"> /not-found (redirects to /) </router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')
6.路由匹配
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // The matching uses path-to-regexp, which is the matching engine used // by express as well, so the same matching rules apply. // For detailed rules, see https://github.com/pillarjs/path-to-regexp const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/' }, // params are denoted with a colon ":" { path: '/params/:foo/:bar' }, // a param can be made optional by adding "?" { path: '/optional-params/:foo?' }, // a param can be followed by a regex pattern in parens // this route will only be matched if :id is all numbers { path: '/params-with-regex/:id(\\d+)' }, // asterisk can match anything { path: '/asterisk/*' }, // make part of th path optional by wrapping with parens and add "?" { path: '/optional-group/(foo/)?bar' } ] }) new Vue({ router, template: ` <div id="app"> <h1>Route Matching</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/params/foo/bar">/params/foo/bar</router-link></li> <li><router-link to="/optional-params">/optional-params</router-link></li> <li><router-link to="/optional-params/foo">/optional-params/foo</router-link></li> <li><router-link to="/params-with-regex/123">/params-with-regex/123</router-link></li> <li><router-link to="/params-with-regex/abc">/params-with-regex/abc</router-link></li> <li><router-link to="/asterisk/foo">/asterisk/foo</router-link></li> <li><router-link to="/asterisk/foo/bar">/asterisk/foo/bar</router-link></li> <li><router-link to="/optional-group/bar">/optional-group/bar</router-link></li> <li><router-link to="/optional-group/foo/bar">/optional-group/foo/bar</router-link></li> </ul> <p>Route context</p> <pre>{{ JSON.stringify($route, null, 2) }}</pre> </div> ` }).$mount('#app')
7.Transition
const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: Home }, { path: '/parent', component: Parent, children: [ { path: '', component: Default }, { path: 'foo', component: Foo }, { path: 'bar', component: Bar } ] } ] }) new Vue({ router, template: ` <div id="app"> <h1>Transitions</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/parent">/parent</router-link></li> <li><router-link to="/parent/foo">/parent/foo</router-link></li> <li><router-link to="/parent/bar">/parent/bar</router-link></li> </ul> <transition name="fade" mode="out-in"> <router-view class="view"></router-view> </transition> </div> ` }).$mount('#app')
const Parent = { data () { return { transitionName: 'slide-left' } }, // dynamically set transition based on route change watch: { '$route' (to, from) { const toDepth = to.path.split('/').length const fromDepth = from.path.split('/').length this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' } }, template: ` <div class="parent"> <h2>Parent</h2> <transition :name="transitionName"> <router-view class="child-view"></router-view> </transition> </div> ` }