全局前置守衛(wèi)
- 可以使用 router.beforeEach 注冊一個全局前置守衛(wèi)
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
to: Route: 即將要進入的目標路由
from: Route: 當前導(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頁</router-link>
<router-link tag="button" to="/news">新聞頁</router-link>
<router-link tag="button" to="/mine">個人中心</router-link>
<!-- <button @click='enterHome'>主頁</button>
<button @click='enterNews'>新聞</button>
<button @click='enterMine'>我的中心</button> -->
<!-- 出口 -->
<!-- 過度動畫可以將出口用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>
`
}
//來個登錄組件
let Login = {
template: `
<div>
<h1>登錄頁</h1>
<button @click="login">登錄</button>
</div>
`,
methods: {
login() {
//設(shè)置個本地存儲,再去前置守衛(wèi)進行登錄判斷
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標簽可以自定義參數(shù),路由元信息
meta: {
needLogin: false
}
},
{
path: '/news',
name: 'news',
component: News,
//meta標簽可以自定義參數(shù)迷扇,路由元信息
meta: {
needLogin: false
}
},
{
path: '/mine',
name: 'mine',
component: Mine,
meta: {
needLogin: true
}
},
]
//路由實例化
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.通過判斷to.fullPath來判斷是否去登錄注冊頁,是就放行
2.通過判斷有沒有本地存儲來決定是否放行
*/
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',
//通過傳自定義參數(shù)來判斷重定向到登錄頁時的頁面信息
params: {
// 比如去個人中心被重定向到登錄蜓席,獲取到了即將前往的路徑
//登陸完成可以直接跳轉(zhuǎn)到對應(yīng)頁面
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)(沒有next參數(shù)器一,因為沒有攔截功能)
router.afterEach((to,from)=>{
})
路由獨享的守衛(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) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
// 不!能厨内!獲取組件實例 `this`
// 因為當守衛(wèi)執(zhí)行前祈秕,組件實例還沒被創(chuàng)建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被復(fù)用時調(diào)用
// 舉例來說雏胃,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id请毛,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時候,
// 由于會渲染同樣的 Foo 組件瞭亮,因此組件實例會被復(fù)用方仿。而這個鉤子就會在這個情況下被調(diào)用。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用
// 可以訪問組件實例 `this`
}
}
路由元信息
- 定義路由的時候可以配置 meta 字段
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
過渡動效
- <router-view> 是基本的動態(tài)組件统翩,所以我們可以用 <transition> 組件給它添加一些過渡效果
<transition name="xxx" mode="out-in">
<router-view></router-view>
</transition>