Vue.js路由管理器 Vue Router
阿新 • • 發佈:2018-12-20
起步
- HTML
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 元件來導航. --> <!-- 通過傳入 `to` 屬性指定連結. --> <!-- <router-link> 預設會被渲染成一個 `<a>` 標籤 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由出口 --> <!-- 路由匹配到的元件將渲染在這裡 n內建元件--> <router-view></router-view> </div>
- JavaScript
// 0. 如果使用模組化機制程式設計,匯入Vue和VueRouter,要呼叫 Vue.use(VueRouter) // 1. 定義 (路由) 元件。 // 可以從其他檔案 import 進來 const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } // 2. 定義路由 // 每個路由應該對映一個元件。 其中"component" 可以是 // 通過 Vue.extend() 建立的元件構造器, // 或者,只是一個元件配置物件。 // 我們晚點再討論巢狀路由。 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 建立 router 例項,然後傳 `routes` 配置 // 你還可以傳別的配置引數, 不過先這麼簡單著吧。 const router = new VueRouter({ routes // (縮寫) 相當於 routes: routes }) // 4. 建立和掛載根例項。 // 記得要通過 router 配置引數注入路由, // 從而讓整個應用都有路由功能 const app = new Vue({ router }).$mount('#app') // 現在,應用已經啟動了!
通過注入路由器,我們可以在任何元件內通過 this.$router 訪問路由器,也可以通過 this.$route 訪問當前路由:
export default { computed: { username () { // 我們很快就會看到 `params` 是什麼 return this.$route.params.username } }, methods: { goBack () { window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/') } } }
routes 選項 (Array)
redirect(重定向 )
//此時訪問/a會跳轉到/b
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
//重定向的目標也可以是一個命名的路由:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
//甚至是一個方法,動態返回重定向目標:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目標路由 作為引數
// return 重定向的 字串路徑/路徑物件
}}
]
})
命名路由
export default [
{
path:'/',
redirect:'/app' //預設跳轉路由
},
{
path: '/app',
//路由命名,可用於跳轉
name: 'app',
}
]
//可用於跳轉
<router-link :to="{name:'app'}">app</router-link>
路由元資訊
定義路由的時候可以配置 meta 欄位:
export default [
{
path:'/',
redirect:'/app' //預設跳轉路由
},
{
path: '/app',
//**相當於HTML的meta標籤**
meta: {
title: 'this is app',
description: 'asdasd'
},
}
]
巢狀路由
export default [
{
path:'/',
redirect:'/app' //預設跳轉路由
},
{
path: '/app',
//子路由 匹配 /app/test
children: [
{
path: 'test',
component: Login
}
]
}
]
路由元件傳參
export default [
{
path:'/',
redirect:'/app' //預設跳轉路由
},
{
path: '/app/:id', // /app/xxx ,元件內部可以通過$route.params.id拿到這個值
// 會把:後面的引數通過props傳遞給元件Todozhong 中
//布林模式
props: true,
//物件模式
props:{id:456}
//函式模式
props: (route) => ({ id: route.query.b }),
component: Todo,
}
]
mode選項(string)
vue-router 預設 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新載入。
如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新載入頁面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
這種模式要玩好,還需要後臺配置支援。
base(string)
應用的基路徑。例如,如果整個單頁應用服務在 /app/ 下,然後 base 就應該設為 "/app/"
return new Router({
routes,
mode: 'history',//預設使用hash#
base: '/base/', //在path前面都會加上/base/,基路徑
})
linkActiveClass(string)
預設值: "router-link-active"
全域性配置 <router-link> 的預設“啟用 class 類名”。
return new Router({
routes,
mode: 'history',//預設使用hash#
base: '/base/', //在path前面都會加上/base/,基路徑
// 點選calss名字
linkActiveClass: 'active-link', //匹配到其中一個子集
linkExactActiveClass: 'exact-active-link',//完全匹配
})
linkExactActiveClass(string)
預設值: "router-link-exact-active"
全域性配置 <router-link> 精確啟用的預設的 class。
scrollBehavior(Function)
路由跳轉後是否滾動
export default () => {
return new Router({
routes,
mode: 'history',//預設使用hash#
base: '/base/', //在path前面都會加上/base/,基路徑
//頁面跳轉是否需要滾動
/*
to:去向路由,完整路由物件
from:來源路由
savedPosition:儲存的滾動位置
*/
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
},
})
}
parseQuery / stringifyQuery (Function)
/每次import都會建立一個router,避免每次都是同一個router
export default () => {
return new Router({
routes,
mode: 'history',//預設使用hash#
base: '/base/', //在path前面都會加上/base/,基路徑
// 路由後面的引數?a=2&b=3,string->object
parseQuery (query) {
},
//object->string
stringifyQuery (obj) {
}
})
}
fallback(boolean)
當瀏覽器不支援 history.pushState 控制路由是否應該回退到 hash 模式。預設值為 true。
如果設定為false,則跳轉後重新整理頁面,相當於多頁應用
<router-link>
過渡動效
<router-view> 是基本的動態元件,所以我們可以用 <transition> 元件給它新增一些過渡效果:
<transition>
<router-view></router-view>
</transition>
高階用法
命名檢視
<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>
const router = new VueRouter({
routes: [
{
path: '/',
components: {
//預設元件
default: Foo,
//命名元件
a: Bar,
b: Baz
}
}
]
})
導航守衛
- 全域性守衛
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './app.vue'
import './assets/styles/global.styl'
// const root = document.createElement('div')
// document.body.appendChild(root)
import createRouter from './config/router'
Vue.use(VueRouter)
const router = createRouter()
// 全域性導航守衛(鉤子)
// 驗證一些使用者是否登入
router.beforeEach((to, from, next) => {
console.log('before each invoked')
next()
// if (to.fullPath === '/app') {
// next({ path: '/login' })
// console.log('to.fullPath :'+to.fullPath )
// } else {
// next()
// }
})
router.beforeResolve((to, from, next) => {
console.log('before resolve invoked')
next()
})
// 每次跳轉後觸發
router.afterEach((to, from) => {
console.log('after each invoked')
})
new Vue({
router,
render: (h) => h(App)
}).$mount("#root")
- 路由獨享的守衛
可以在路由配置上直接定義 beforeEnter 守衛:
export default [
{
path:'/',
redirect:'/app' //預設跳轉路由
},
{
path: '/app',
// 路由獨享的守衛鉤子
beforeEnter(to, from, next) {
console.log('app route before enter')
next()
}
component: Todo,
}
]
- 元件內的守衛
export default {
//進來之前
beforeRouteEnter(to, from, next) {
// 不!能!獲取元件例項 `this`
// 因為當守衛執行前,元件例項還沒被建立
console.log("todo before enter", this); //todo before enter undefined
//可以通過傳一個回撥給 next來訪問元件例項。在導航被確認的時候執行回撥,並且把元件例項作為回撥方法的引數。
next(vm => {
// 通過 `vm` 訪問元件例項
console.log("after enter vm.id is ", vm.id);
});
},
//更新的時候
beforeRouteUpdate(to, from, next) {
console.log("todo update enter");
next();
},
// 路由離開
beforeRouteLeave(to, from, next) {
console.log("todo leave enter");
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
//以通過 next(false) 來取消。
next(false)
}
},
props:['id'],
components: {
Item,
Tabs
},
mounted() {
console.log(this.id)
},
};
路由懶載入
參考:路由懶載入