路由(vue-router)

1、安装并使用

  1. npm i vue-router@3 / yarn add vue-router@3

    • vue-router3以上的版本只能用于vue3,vue2只能用3或以下的版本
  2. main.js引入

    import Vue from 'vue'
    import App from './App.vue'
    
    import router from './router';
    
    new Vue({
      router,
      render: h => h(App),
    }).$mount('#app')
    
    
  3. 创建router/index.js

    • index.js

      import Vue from 'vue'
      import VueRouter from 'vue-router';
      
      Vue.use(VueRouter);
      
      const router = new VueRouter({
        routes: [
          {
            path: '/home',
            component: () => import("../xxx/xxx/xxx.vue")
          },
          {
            path: '/about',
            component: () => import("../xxx/xxx/xxx.vue")
          },
        ]
      })
      
      export default router
      
  4. 使用

    <!-- 路由切换 -->
    <!-- active-class:路由激活后的样式 -->
    <router-link to='/home'>到home</router-link>
    <router-link to='/about'>到about</router-link>
    
    <!-- 指定展示的位置 -->
    <router-view></router-view>
    
  5. 注意点:

    • 路由组件通常单独创建一个文件夹存放,一般该文件夹名称为pages或views,一般组件通常放在components文件夹中
    • 通过切换,“隐藏”了的路由组件,默认是被销毁了,需要的时候再去挂载
    • 每个组件都有自己的$route属性,里面存储自己的路由信息
    • 整个应用只有一个router,可以通过$router属性获取到

2、嵌套(多级)路由

  • 配置router/index.js

    import Vue from 'vue'
    import VueRouter from 'vue-router';
    
    Vue.use(VueRouter);
    
    const router = new VueRouter({
      routes: [{
          path: '/home',
          component: () => import("../components/home.vue")
        },
        {
          path: '/about',
          component: () => import("../components/about.vue"),
          children: [{
            // 两种写法:
            // 1、直接写子路由的path,不用加斜杠,vue会自动拼接
            // path: 'xxxx',
            // 2、自己拼接path,必须携带父路由的path,格式:/父路由/子路由
            path: '/about/xxxx',
            component: () => import("../xxx/xxxx.vue")
          }]
        },
      ]
    })
    
    export default router
    
  • about中使用

    注意:跳转时,必须写完整的子路由path地址

    <!-- 使用路由跳转 -->
    <!-- active-class:路由激活后的样式 -->
    <router-link active-class="active" to='/home/xxxx'>到home的子路由</router-link>
    
    <!-- 展示的位置 -->
    <router-view></router-view>
    

3、命名路由

  1. 配置router/index.js

    import Vue from 'vue'
    import VueRouter from 'vue-router';
    
    Vue.use(VueRouter);
    
    const router = new VueRouter({
      routes: [{
          name:'home',
          path: '/home',
          component: () => import("../components/home.vue")
        },
        {
          name: 'about',
          path: '/about',
          component: () => import("../components/about.vue"),
        },
      ]
    })
    
    export default router
    
  2. 跳转

    <router-link :to="{name: 'home'}"> to home</router-link>
    

4、路由传参

4.1、query传参

  1. html中传参

    • 传参

      <!-- 字符串传参 -->
      <router-link active-class="active" :to="`/home?id=${111}&name=${'小明'}`">到home</router-link>
      
      <!-- 对象传参 -->
      <router-link active-class="active" :to="{
      	path:'/home',
          query:{
              id:111,
                  name:'小明'
      	}
      }">到home</router-link>
      
      <!-- 使用命名路由query传参 -->
      <router-link active-class="active" :to="{
      	name:'/home',
          query:{
              id:111,
                  name:'小明'
      	}
      }">到home</router-link>
      
  2. js中传参

    this.$router.push({
        path:'/home',
        query:{
            id:111,
            name:'小明'
        }
    })
    
    // 使用命名路由query传参
    this.$router.push({
        name:'home',
        query:{
            id:111,
            name:'小明'
        }
    })
    
  3. 接收参数

    mounted() {
        console.log(this.$route.query.xxxx);
    },
    

4.2、params传参

params传参只能使用name,不能使用path

  1. html中传参

    • 使用对象传参

          <router-link active-class="active" :to="{
            name:'home',
            params:{
              id:111,
              name:'小明'
            }
          }">到home</router-link>
      
    • 使用字符串

      params使用字符串方式传参,需要在router/index.js中配置占位符

      配置router/index.js:

      import Vue from 'vue'
      import VueRouter from 'vue-router';
      
      Vue.use(VueRouter);
      
      const router = new VueRouter({
        routes: [{
            name:'home',
            path: '/home/:id/:name',
            component: () => import("../components/home.vue")
          },
          {
            name: 'about',
            path: '/about/:id/:name',
            component: () => import("../components/about.vue"),
          },
        ]
      })
      
      export default router
      

      使用

      <router-link active-class="active" to='/about/111/小明'>到about</router-link>
      
  2. js中传参

    this.$router.push({
        name:'home',
        params:{
            id:111,
            name:'小明'
        }
    })
    
  3. 接收参数

    mounted() {
        console.log(this.$route.params.xxxx);
    },
    

5、路由的props配置

  1. 第一种写法

    这种写法,是在router/index.js配死了的,也就是说,在router/index.js中配置的什么字段,在组件中就只能接收什么字段并且这种方法是以字符串方式返回

    • 配置router/index.js:

      import Vue from 'vue'
      import VueRouter from 'vue-router';
      
      Vue.use(VueRouter);
      
      const router = new VueRouter({
        routes: [{
            name:'home',
            path: '/home',
            props:{id:'111',name:'小明'},
            component: () => import("../components/home.vue")
          }
        ]
      })
      
      export default router
      
    • home组件中接收

      <template>
        <div class="home">
          1111
        </div>
      </template>
      
      <script>
      export default {
        name: 'home',
        props:['id','name'],
      }
      </script>
      
      <style scoped>
      
      </style>
      
  2. 第二种写法

    配置props为一个boolean值,为true时,会将该组件收到的所有params参数,以props的形式传给about组件,并且值为一个对象

    • 配置router/index.js:

      import Vue from 'vue'
      import VueRouter from 'vue-router';
      
      Vue.use(VueRouter);
      
      const router = new VueRouter({
        routes: [
          {
            name: 'about',
            path: '/about',
            props:true,
            component: () => import("../components/about.vue"),
          },
        ]
      })
      
      export default router
      
    • 在app.vue传入params

      <router-link active-class="active" :to="{
         name:'about',
         params:{
           id:111,
           name:'小明'
         }
      }">到about</router-link>
      
    • about组件中接收

      <template>
        <div class="about">
          <button>{{id}}{{name}}</button>
        </div>
      </template>
      
      <script>
      export default {
        name: 'about',
        props:['id','name'],
      }
      </script>
      
      <style scoped>
      </style>
      
  3. 第三种写法

    配置props为函数,该函数会接收到一个$route参数,以props的形式传给组件,并且值为一个对象,接收参数的方式与前面两种一致

    import Vue from 'vue'
    import VueRouter from 'vue-router';
    
    Vue.use(VueRouter);
    
    const router = new VueRouter({
      routes: [{
          name:'home',
          path: '/home',
          props($route) {
            return {
              id: $route.query.id,
              name: $route.query.name
            }
          },
          component: () => import("../components/home.vue")
        },
        {
          name: 'about',
          path: '/about',
          props($route) {
            return {
              id: $route.params.id,
              name: $route.params.name
            }
          },
          component: () => import("../components/about.vue"),
        },
      ]
    })
    
    export default router
    

6、router-link的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式

  2. 浏览器的历史记录有两种写入方式,分别为push和replace,push是追加历史记录,replace是替换当前记录,默认为push

  3. 如何开启replace:

    <router-link replace to="/xxx"></router-link>
    

7、前进,后退,替换

// query传参    
this.$router.push({
    path:'/xxxx',
    query:{}
})

// params传参    
this.$router.push({
    name:'xxxx',
    params:{}
})

// params传参    
this.$router.replace({
    name:'xxxx',
    // path:'/xxxx',
    // query:{},
    params:{}
})

// 前进
this.$router.forward()

// 后退
this.$router.back()

// 传入的参数为正数就是前进,负数为后退
this.$router.go(-1)

8、keep-alive

  1. 作用:让不展示的路由组件保持挂载,不被销毁

  2. 代码:

    <!-- keep-alive:缓存路由组件 -->
    <!-- include:只缓存某一个组件,若要缓存多个组件,可写一个数组 :include="['xxx','xxx']" -->
    <keep-alive include="home">
        <!-- 展示的位置 -->
        <router-view></router-view>
    </keep-alive>
    

9、生命周期activated&deactivated

  1. 作用:路由组件所独有的两个钩子函数,用于捕获路由组件的激活状态

  2. 详情:

    activated:路由组件激活时触发

    deactivated:路由组件销毁时触发

10、路由守卫

  1. 作用:对路由进行权限控制
  2. 分类:全局守卫,独享守卫,组件内守卫

10.1、全局前置路由守卫

// 全局前置路由守卫
// 初始化的时候被调用,每次路由切换之前被调用
router.beforeEach((to,from,next) => {
    // to:要去的目标路由
    // from:当前所在的路由
    // next:放行
    
    // 判断有没有登录
    if (localStorage.getItem("token")) {
        // 如果登录过允许跳转
        next();
    } else {
        // 如果没登陆过,但要跳转到登录页,允许跳转
        if (to.path === "/login") {
            next();
        } else {
            // 否则跳转到登录页
            next("/login");
        }
    } 
})

10.2、全局后置路由守卫

// 全局后置路由守卫
// 初始化的时候被调用,每次路由切换之后被调用
router.afterEach((to,from,next) => {
    // to:要去的目标路由
    // from:当前所在的路由
    // next:放行
})

10.3、独享路由守卫

作用:某一个路由所独享的路由守卫

import Vue from 'vue'
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
  routes: [{
      name: 'xxxx',
      path: '/xxxx',
      // 独享路由守卫
      // 组件初始化的时候被调用,在路由切换之前被调用
      beforeEnter: (to, from, next) => {
        // to:要去的目标路由
        // from:当前所在的路由
        // next:放行
      },
      component: () => import("../xxxx/xxxx.vue"),
      children: [{
        name: 'xxxx',
        path: '/xxxx',
        // 独享路由守卫
        // 组件初始化的时候被调用,在路由切换之前被调用
        beforeEnter: (to, from, next) => {
          // to:要去的目标路由
          // from:当前所在的路由
          // next:放行
        },
        component: () => import("../xxxx/xxxx.vue"),
      }]
    },
  ]
})

export default router

10.4、组件内路由守卫

  1. beforeRouteEnter

      // 通过路由规则, 进入该组件之前调用
      beforeRouteEnter(to,from,next){
          // to:要去的目标路由
          // from:当前所在的路由
          // next:放行
      }
    
  2. beforeRouteLeave

      // 通过路由规则, 离开该组件之前调用
      beforeRouteLeave(to,from,next){
          // to:要去的目标路由
          // from:当前所在的路由
          // next:放行
      }
    

11、hash和history模式

  1. 对于url来说,什么是hash至?——#及其后面的内容就是hash值。
  2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器。
  3. hash模式:
    • 地址中永远带着#号,不美观
    • 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
    • 兼容性较好
  4. history模式:
    • 地址干净、美观
    • 兼容性和hash模式相比略差
    • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

路由(vue-router)
http://localhost:8090//archives/lu-you-vue-router
作者
龟龟
发布于
2020年12月18日
更新于
2024年08月28日
许可协议