全局前置守衛(wèi)
- 可以使用 router.beforeEach 注冊(cè)一個(gè)全局前置守衛(wèi)
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
to: Route: 即將要進(jìn)入的目標(biāo)路由
from: Route: 當(dāng)前導(dǎo)航正要離開的路由
next:類似于中間件的攔截器
案例分析
全局前置守衛(wèi)模擬登錄鑒權(quán)案例
<style>
html {
overflow-x: hidden;
height: 1500px;
}
.router-link-active {
background: rgb(29, 109, 29);
}
h1 {
color: cornflowerblue;
}
.ani-enter {
transform: translateX(-100%);
opacity: 0;
}
.ani-enter-active,
.ani-leave-active {
transition: all .5s;
}
.ani-leave-to {
transform: translateX(100%);
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<router-link tag="button" to="/home">home頁(yè)</router-link>
<router-link tag="button" to="/news">新聞頁(yè)</router-link>
<router-link tag="button" to="/mine">個(gè)人中心</router-link>
<!-- <button @click='enterHome'>主頁(yè)</button>
<button @click='enterNews'>新聞</button>
<button @click='enterMine'>我的中心</button> -->
<!-- 出口 -->
<!-- 過(guò)度動(dòng)畫可以將出口用transition包裹 -->
<transition name="ani" mode="out-in">
<router-view></router-view>
</transition>
</div>
</body>
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<script>
//定義組件
let Home = {
template: `
<div>
<h2>Home</h2>
</div>
`
}
let News = {
template: `
<div>
<h2>News</h2>
</div>
`
}
let Mine = {
template: `
<div>
<h2>Mine</h2>
</div>
`
}
//來(lái)個(gè)登錄組件
let Login = {
template: `
<div>
<h1>登錄頁(yè)</h1>
<button @click="login">登錄</button>
</div>
`,
methods: {
login() {
//設(shè)置個(gè)本地存儲(chǔ),再去前置守衛(wèi)進(jìn)行登錄判斷
localStorage.setItem('access_token', 'blackLetter');
console.log(this.$route);
if (this.$route.params.from) {
this.$router.push(this.$route.params.from)
} else {
this.$router.push('/home')
}
}
}
}
const routes = [
{
path: "/",
redirect: '/home',
},
{
path: '/login',
name: 'login',
component: Login,
meta: {
}
},
{
path: '/home',
name: 'home',
component: Home,
//meta標(biāo)簽可以自定義參數(shù),路由元信息
meta: {
needLogin: false
}
},
{
path: '/news',
name: 'news',
component: News,
//meta標(biāo)簽可以自定義參數(shù),路由元信息
meta: {
needLogin: false
}
},
{
path: '/mine',
name: 'mine',
component: Mine,
meta: {
needLogin: true
}
},
]
//路由實(shí)例化
const router = new VueRouter({
routes,
mode:'hash',
scrollBehavior(to, from, savedPosition) {
console.log(savedPosition);
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
})
//定義全局前置守衛(wèi)
router.beforeEach((to, from, next) => {
// to 去哪 next 類似于中間件,攔截的關(guān)鍵,也可以帶參數(shù)
console.log(to);
// console.log(from);
/*
1.通過(guò)判斷to.fullPath來(lái)判斷是否去登錄注冊(cè)頁(yè),是就放行
2.通過(guò)判斷有沒(méi)有本地存儲(chǔ)來(lái)決定是否放行
*/
console.log(to.meta.needLogin)
if (to.fullPath === '/login' || to.fullPath === '/register') {
next()
} else {
//判斷是否需要登錄 ,不需要就放行,路由中有設(shè)置meta屬性
if (to.meta.needLogin) {
let access_token = localStorage.getItem('access_token');
if (access_token) {
next();
} else {
// next('/login')
// console.log(to.fullPath);
next({
name: 'login',
//通過(guò)傳自定義參數(shù)來(lái)判斷重定向到登錄頁(yè)時(shí)的頁(yè)面信息
params: {
// 比如去個(gè)人中心被重定向到登錄,獲取到了即將前往的路徑
//登陸完成可以直接跳轉(zhuǎn)到對(duì)應(yīng)頁(yè)面
from: to.fullPath
}
})
}
} else {
next()
}
}
})
//全局后置守衛(wèi)
router.afterEach((to, from) => {
// ...
})
let vm = new Vue({
el: '#app',
router,
methods: {
// enterHome() {
// this.$router.push('/home')
// },
// enterNews() {
// this.$router.push({ name: 'news' })
// },
// enterMine() {
// this.$router.push('/mine')
// },
}
})
</script>
全局后置守衛(wèi)(沒(méi)有next參數(shù),因?yàn)闆](méi)有攔截功能)
router.afterEach((to,from)=>{
})
路由獨(dú)享的守衛(wèi)
- 可以在
上直接定義 beforeEnter 守衛(wèi)
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
組件內(nèi)的守衛(wèi)
- 可以在
內(nèi)直接定義以下路由導(dǎo)航守衛(wèi)
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
// 不!能!獲取組件實(shí)例 `this`
// 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒(méi)被創(chuàng)建
},
beforeRouteUpdate (to, from, next) {
// 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
// 舉例來(lái)說(shuō),對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候,
// 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。
// 可以訪問(wèn)組件實(shí)例 `this`
},
beforeRouteLeave (to, from, next) {
// 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
// 可以訪問(wèn)組件實(shí)例 `this`
}
}
路由元信息
- 定義路由的時(shí)候可以配置 meta 字段
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
過(guò)渡動(dòng)效
- <router-view> 是基本的動(dòng)態(tài)組件,所以我們可以用 <transition> 組件給它添加一些過(guò)渡效果
<transition name="xxx" mode="out-in">
<router-view></router-view>
</transition>