vue-router 使用

169 阅读1分钟

1.安装

​ vue add router

1.1标签方式

<nav><router-link to="/">首页</router-link> 
<router-link to="/about">管理</router-link>
</nav>
<router-view></router-view>

1.2 动态路由匹配

//路由配置
router/index.js //当前:name 是一个通配符,用于使用的时候动态传入参数
{ path: '/course/:name', component: () => import('../views/Detail.vue') }
//列表页面
<router-link :to="`/course/${c.name}`">
  {{ c.name }} - {{ c.price | currency('¥') }} 
 </router-link>

//详情
<div> 
<h2>detail page</h2> 
<p>{{$route.params.name}} ...</p> 
</div>
//404 页面处理
{ // 会匹配所有路径 
  path: '*', component: () => import('../views/404.vue')
}
 

1.3嵌套路由

<router-link :to="`/about/${c.name}`"> 
{{ c.name }} - {{ c.price | currency('¥') }} 
</router-link>

<router-view></router-view>
//router/index.js
 { path: '/about', name: 'about', 
   component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'), 
   children:   [ { path: ':name', component: () => import('../views/Detail.vue') },   ] 
}
//detail.vue 嵌套路由由于有缓存,不会再次执行created/mount方法,所以可以通过监听$route触发逻辑
export default { watch: 
{ 
  $route: { 
    handler: () => { console.log("$route change"); },immediate: true } 
  } 
};

1.4动态路由

//动态路由

// 字符串 router.push('home') 
// 对象 
router.push({ path: 'home' }) 
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }}) 
// 带查询参数,变成 /register?plan=private 
router.push({ path: 'register', query: { plan: 'private' }})

命名路由
const router = new VueRouter({ 
routes: [ { path: '/user/:userId', name: 'user', component: User } ] 
})
//调用1
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
//调用2
router.push({ name: 'user', params: { userId: 123 }})

2.路由守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程 中:全局, 单个路由独享, 组件级。

2.1全局

// to: Route: 即将要进入的目标 路由对象
// from: Route: 当前导航正要离开的路由
// next: Function: 一定要调用该方法来 resolve 这个钩子。
router.beforeEach((to, from, next) => {
  if (to.meta.auth) { 
    if (window.isLogin) { next() 
     } else {
       next('/login?redirect='+to.fullPath)
     } 
  } else {
    next()
  }  
})
<template> 
<div>
    <button @click="login" v-if="!isLogin">登录</button> 
    <button @click="logout" v-else>登出</button> 
</div> 
</template> 

<script> 
export default { 
    methods: { 
        login() { 
            window.isLogin = true 
            this.$router.push(this.$route.query.redirect) 
        },
        logout() { 
            window.isLogin = false 
        } 
    },
    computed: { 
        isLogin() { 
            return window.isLogin 
        } 
    }, 
} 
</script> 

2.2单个路由独享

{ 
  path: '/about', 
  name: 'about', 
  // ... 
  beforeEnter(to, from, next) { 
    if (to.meta.auth) { 
      if (window.isLogin) { 
      next() 
      } else { 
      next('/login?redirect=' + to.fullPath) 
      }
    } else { 
      next()
    } 
  } 
}, 

2.3组件级

//index.vue 
export default {
    beforeRouteEnter(to, from, next) {
        if (window.isLogin) {
          next();
        } else {
          next("/login?redirect=" + to.fullPath);
        }
     },
}

3数据请求

//路由导航前
export default {
  // 组件未渲染,通过给next传递回调访问组件实例
  beforeRouteEnter(to, from, next) {
    getPost(to.params.id, (post) => {
      next((vm) => vm.setData(post));
    });
  },

  // 组件已渲染,可以访问this直接赋值
  beforeRouteUpdate(to, from, next) {
    this.post = null;
    getPost(to.params.id, (post) => {
      this.setData(post);
      next();
    });
  },
};
//路由导航后
created () {
    this.fetchData() //页面加载
},
watch: 
{ '$route': 'fetchData' } //路由变化时候加载数据

4.动态路由

// 全局守卫 + 动态路由添加
router.beforeEach((to, from, next) => {
  // 判断路由是否需要守卫
  // meta数据
  if (to.meta.auth) {
    // 是否登录
    if (window.isLogin) {
      next()
    } else {
      next('/login?redirect='+to.fullPath)
    }
  } else {
    next()
  }
})

// Login.vue用户登录成功后动态添加路由
  login() {
    window.isLogin = true;
    this.$router.addRoutes([
      {
        path: "/about", //...
      },
    ]);
    const redirect = this.$route.query.redirect || "/";
    this.$router.push(redirect);
  },

5路由组件缓存

  1. 使用include或exclude时要给组件设置name
export default {
    name:"about", //定义组件名称
    ...
}
  1. 两个特别的生命周期:activated、deactivated
  <keep-alive include="about" max=10>
    <router-view></router-view>
  </keep-alive>

6路由懒加载

//动态加载
() => import("../views/About.vue")
//按组group-about打包
() => import(/* webpackChunkName: "group-about" */ "../views/About.vue")
() => import(/* webpackChunkName: "group-about" */ "../views/Detail.vue")