主結構
/home /about /user/profile /user/posts
+------------------+ +-----------------+ +------------------+ +-----------------+
| Home | | About | | User | | User |
| +--------------+ | | +-------------+ | | +--------------+ | | +-------------+ |
| | | | +------------> | | | | +------------> | | UserProfile | | +------------> | | UserPosts | |
| | | | | | | | | | | | | | | |
| +--------------+ | | +-------------+ | | +--------------+ | | +-------------+ |
+------------------+ +-----------------+ +------------------+ +-----------------+
App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/user">User</router-link>
</div>
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
.user a.router-link-exact-active.router-link-active {
color: #42b983;
}
.home h1 {
color: #42b983;
}
.user h1 {
color: orange
}
</style>
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
// Home.vue
{
path: '/',
name: 'home',
component: () => import( '../views/Home.vue')
},
// About.vue
{
path: '/about',
name: 'about',
component: () => import('../views/About.vue')
},
// User.vue
{
path: '/user',
name: 'user',
component: () => import('../views/User.vue'),
// 嵌套 UserProfile.vue、 UserPosts.vue
children: [
{
path: '/profile',
component: () => import('../views/UserProfile.vue')
},
{
path: '/posts',
component: () => import('../views/UserPosts.vue')
}
]
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
render: function (h) { return h(App) }
}).$mount('#app')
Home.vue
<template>
<div class="home">
<H1>This is an home page</H1>
</div>
</template>
<script>
export default {
name: 'Home',
}
</script>
About.vue
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
User.vue
<template>
<div class="user">
<H1>This is an user page</H1>
<router-link to="profile">UserProfile</router-link> |
<router-link to="posts">Userposts</router-link>
<router-view />
</div>
</template>
<script>
export default {
name: 'User',
}
</script>
UserProfile.vue
<template>
<div class="profile">
<H2>This is an UserProfile page</H2>
</div>
</template>
UserPosts.vue
<template>
<div class="posts">
<H2>This is an UserPosts page</H2>
</div>
</template>
全局前置守衛
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
/* 比如做登陸驗證
if (to.name !== 'Home' && !isAuthenticated) next({ name: 'Home' })
else next()
*/
document.title = to.matched[0].name
next()
})
全局后置鈎子
router.afterEach((to, from) => {
// 注冊全局后置鈎子,這些鈎子不會接受 next 函數也不會改變導航本身
// ...
})
路由獨享守衛
// 你可以在路由配置上直接定義 beforeEnter 守衛:
const router = new VueRouter({
routes: [
{
path: '/Home',
component: () => import( '../views/Home.vue'),
beforeEnter: (to, from, next) => {
// ...
next()
}
}
]
})
// 這些守衛與全局前置守衛的方法參數是一樣的
組件內的守衛
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 `this`
// 因為當守衛執行前,組件實例還沒被創建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被復用時調用
// 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由於會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鈎子就會在這個情況下被調用。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 可以訪問組件實例 `this`
}
}
beforeRouteEnter
/*
beforeRouteEnter 守衛 不能 訪問 this,因為守衛在導航確認前被調用,因此即將登場的新組件還沒被創建。
不過,你可以通過傳一個回調給 next來訪問組件實例。在導航被確認的時候執行回調,並且把組件實例作為回調方法的參數
*/
beforeRouteEnter (to, from, next) {
next(vm => {
// 通過 `vm` 訪問組件實例
})
}
/* 注意
beforeRouteEnter 是支持給 next 傳遞回調的唯一守衛。對於 beforeRouteUpdate 和 beforeRouteLeave 來說,
this 已經可用了,所以不支持傳遞回調,因為沒有必要了。
*/
beforeRouteUpdate
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
beforeRouteLeave
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
// 這個離開守衛通常用來禁止用戶在還未保存修改前突然離開。該導航可以通過 next(false) 來取消
完整的導航流程
導航被觸發。
在失活的組件里調用 beforeRouteLeave 守衛。
調用全局的 beforeEach 守衛。
在重用的組件里調用 beforeRouteUpdate 守衛 (2.2+)。
在路由配置里調用 beforeEnter。
解析異步路由組件。
在被激活的組件里調用 beforeRouteEnter。
調用全局的 beforeResolve 守衛 (2.5+)。
導航被確認。
調用全局的 afterEach 鈎子。
觸發 DOM 更新。
調用 beforeRouteEnter 守衛中傳給 next 的回調函數,創建好的組件實例會作為回調函數的參數傳入。
路由元信息
/*
定義路由的時候可以配置 meta 字段,分別給Home.vue加入路由元素 meta: { requiresAuth: true } ,
給About.vue加入路由元素 meta: { requiresAuth: false}
*/
const routes = [
{
path: '/',
name: 'Home',
component: () => import( '../views/Home.vue'),
meta: { requiresAuth: true }
},
// About.vue
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue'),
meta: { requiresAuth: false}
},
// Login.vue
{
path: '/login',
name: 'Login',
component: () => import( '../views/Login.vue'),
}
]
// 全局前置守衛 判斷 requiresAuth 的狀態 ,false 跳轉登陸頁
router.beforeEach((to, from, next) => {
// console.log('from------從那個路由') console.log(from)
// console.log('to--------跳轉到那個路由') console.log(to)
if(to.fullPath !== '/login' && !to.matched[0].meta.requiresAuth) next('login')
else next()
})
keep-alive
include 、exclude
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<keep-alive exclude="About" include="Home,User">
<router-view />
</keep-alive>
</div>
</template>
// 本頁:App.vue
// include 值為組件中的name、include 標記的組件會緩存
// exclude 值為組件中的name、exclude 標記的組件不會緩存
deactivated、deactivated
<template>
<div class="home">
<H1>This is an home page</H1>
</div>
</template>
export default {
name: 'Home',
components: {
},
data(){
return {
path :'/news'
}
},
mounted(){
console.log(this.$route.query)
},
method: {
},
create(){
console.log('-----------------------------Home created 創建')
},
destroyed(){
console.log('---------------------------Home destroyed 銷毀')
},
activated(){
//活躍的
console.log('---------------------------Home activated活躍' + this.path)
this.$router.push(this.path)
},
deactivated(){
//不活躍的
console.log('---------------------------Home deactivated不活躍' + this.path)
},
beforeRouteLeave (to, from, next){
//前置導航,頁面離開時執行
this.path = this.$route.path
next()
}
}
// 只有使用keep-alive時 才會調用 activated() deactivated()