vue-router 配置

主结构

/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()
posted @ 2020-10-26 11:28  BingNiTer  阅读(487)  评论(3编辑  收藏  举报