vue router核心知识点

文章详细介绍了VueRouter的安装、配置过程,包括不同Vue版本对应的不同Router版本,以及如何创建路由映射表。还讲解了组件中如何使用router-view和router-link进行声明式导航,以及编程式导航的实现。此外,文章探讨了params和query的参数传递方式,以及hash和history路由模式。最后,重点阐述了导航守卫的全局和局部使用,包括beforeEach、afterEach等,并提到了路由的动态添加和路由组件与非路由组件的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.install vue router

vue2.x对应vue router3.x版本
vue3.x对应vue router4.x版本
npm install vue-router@3.x / vue-router@4.x

2.router文件配置

1.导入VueRouter
2.将VueRouter绑定到Vue上
3.创建VueRouter实例并且传入参数配置项
4.创建router路由映射表

import Vue from 'vue';
import VueRouter from 'vue-router';
import Products from '../src/components/homeComponents/productsMy';

Vue.use(VueRouter);

const routes = [{
        path: '/', //路由地址
        name: 'landing', //给路由起个名字,传参的时候会用到
        redirect: '/home' //路由重定向
    },{
        path:'/home',
        name: 'home',
        component: ()=>import('../src/components/homeMy.vue'), //异步加载该component
        children: [{ //配置子路由
            path: '/home/products',
            name: 'home_products',
            component: Products
        }]
    },
    {
        path:'/user',
        name: 'user',
        component: ()=>import('../src/components/userMy.vue')
    },
    {
        path:'/list/:id', //动态路由匹配
        name: 'list',
        component: ()=>import('../src/components/listMy.vue')
    },
    {
        path: '*', //剩余匹配,只能放在最后一项,当所有上面的路由没有被匹配到的时候,匹配到该路由
        redirect: '/home'
    }
]

const router = new VueRouter({
    routes, //路由映射表
    mode: 'hash' //路由模式hash or history
})

export default router;

3.组件配置及使用

1.需要给用到路由的组件在模版里面配置router-view标签,相当于指定这些组件是受路由管控的
2.在模版里面使用router-link配置to='字符串路由’或者v-bind:to="JS表达式"跳转到指定路由对应的页面
3.编程式导航,在JS代码里面通过this.$router.push(参数和上面to的值相同)

//params 传参
<template>
  <div class="">home
    <router-link to='/home/products'>to product</router-link>
    <br>
    <router-link :to="{ name:'list', params:{id:1,g:'e'} }">to list</router-link>
    <router-view></router-view>
    <button @click="f">to list2</button>
  </div>
</template>

<script>

export default {
    data() {
        return {};
    },
    methods:{
        f(){
            setTimeout(()=>{
                // 编程式导航 push的参数等同于to的参数
                // push replace go back go(-1) === back  
                // push会新增历史记录, replace不会新增历史记录
                this.$router.push('/list/3')
            }, 1000)
        }
    }
}
</script>
// query传参
<template>
  <div class="">
    <h1>products</h1>
    <ul>
    <li>
      <router-link :to="{name: 'user', query:{a:1, b:'vv'}}">子路由组件button</router-link>
    </li>
  </ul>
  </div>
</template>

<script>
export default {
  data () {
    return {
    }
  },
}
</script>

<style scoped lang="scss"></style>

hash路由和history路由
1. hash路由利用的是hashchange事件
2. history路由利用的是popstate事件和两个方法 pushState和replaceState方法

路由传参的方式params和query
1. query传参会在url地址后面拼接参数
2. params传参是通过动态路由匹配

params传参刷新页面参数丢失问题:
如果在路由映射表里面配置则不会丢失,没配置会丢失
会丢失的参数还可以存储在vuex或者存在localStorage里面
4.修改选中路由的样式
a.第一种修改方式,修改全局的,不推荐使用
在router配置文件里面配置linkActiveClass(路由被当前激活路由包含)和linkExcatActiveClass(路由和当前激活路由完全精确匹配)

//在router实例文件
const router = new VueRouter({
    routes,
    mode: 'hash',
    //不推荐在此处修改选中路由的样式,可以在模版页面使用active-class或者active-exact-class进行局部修改
    // linkActiveClass: 'qqq',  //修改全局的路由的样式,当路由包含的时候
    // linkExactActiveClass: 'www' //修改全局的路由的样式,当路由完全匹配的时候
})

b.第二种修改方式,修改局部的
active-class 和exact-active-class

//在组件文件里面修改
<template>
    <div>
        <router-link :to="{path:'home'}">首页</router-link>
        <router-link to="/user" active-class="www" exact-active-class="uuu">我的</router-link>
        <router-link to="/user?q=1">我的3</router-link>
        <router-link to="/home/qqq">qqq</router-link>
        <router-view></router-view>
    </div>
</template>

4.导航守卫

导航守卫有3种形式,全局守卫,路由守卫和组件守卫。
a.最常用的是全局前置守卫,在路由跳转之前做一些权限校验,满足权限则执行next方法到下一步,不满足权限则跳转到指定路由页面。
b.除了全局后置守卫,所有的导航守卫方法都接收3个参数(to, from, next),to和from相当于$route对象(包含path,match,params, query等信息),并且必须要执行next方法到下一步;全局后置守卫只接收两个参数(to, from)并且不会改变导航本身。
c.只有组件内前置守卫的next函数可以接受一个回调函数作为参数,并且组件实例本身被作为参数传递给回调函数

1.全局守卫

// 全局前置守卫
router.beforeEach((to, from, next )=>{
    // to 和 from的格式类似于$route
    // if(to.path === '/user') next();
    // 必须调用next到下一步,next的参数等同于push的参数
    if(!to.meta.role){
        document.title = "test";
        next();
        return;
    }
    if(to.meta.role.includes(to.meta.title)) document.title = to.meta.title;
    next();
    // next('/user'); // 死循环,使用next进行路径跳转的时候也会触发前置守卫
})

//全局后置守卫
router.afterEach(()=>{
    // console.log(to, from)
})

//全局解析守卫
router.beforeResolve,和beforeEach类似,区别是在导航确认之前,同时在所有组件内守卫和异步路由组件解析之后调用

2.路由守卫

路由守卫是配置在路由映射表里
beforeEnter: (to, from, next)=>{…}

    {
        path:'/list/:id',
        name: 'list',
        component: ()=>import('../src/components/listMy.vue'),
        beforeEnter: (to, from, next)=>{ //路由配置守卫
            // 与全局前置守卫的方法参数一致
            // console.log(to, from, next)
            next()
        }
    },

3.组件内路由守卫

beforeRouteEnter(to, from, next){…}

组件内进入守卫, 不能访问this, 因为守卫是在导航确认前被调用,因此新组件还没被创建,可以通过给next传一个回调函数来访问组件实例,在导航被确认的时候执行回调,并且把组件实例作为参数传递给该回掉函数

beforeRouteUpdate(to, from, next){…}

组件内更新守卫,当前路由改变,但是当前组件被复用时调用

beforeRouteLeave(to, from, next){…}

组件内离开守卫,导航离开该组件的对应路由时调用该守卫

//组件内进入守卫
 beforeRouteEnter(to, from, next){
    // 在渲染该组件的对应路由被confirm前调用
    //不能访问组件实例this, 因为组件实例还没有被创建
    // console.log(to, from)
    next();
    //next(vm => {console.log(vm)}) //vm为当前组件实例
  },
  
  //组件内更新守卫
  beforeRouteUpdate(to, from ,next){
    //当前路由改变,但是当前组件被复用时调用
    //例如访问/foo/:id, 当路由在/foo/1 与 /foo/2之间切换的时候, 由于会渲染同样的Foo组件,所以组件会被复用
    //可以访问组件实例
    console.log('路由切换了,但是渲染的仍是同个组件')
    next()
  },
  
  //组件内离开守卫
  beforeRouteLeave(to, from, next){
    //组件离开当前组件对应路由时触发, 或者获取到组件实例this
    const res = confirm('确认离开吗?')
    if(res){
      console.log('确认离开')
      next();
    }else{
      next(false);
    }
  }

导航实例调用方法addRoute

router.addRoute({path:‘…’, component:‘…’})
添加一条新路由规则, 可以接受两个参数,第一个参数可以指定父路由的name,第二个参数为新路由对应的路由映射对象,包含path, component等

let obj = { // 创建路由映射表在编译阶段将组件加载进来
    '../src/components/homeComponents/qqqMy.vue': () => import('../src/components/homeComponents/qqqMy.vue')
}

let ary = [{
    path: '/home/qqq',
    componentURL: '../src/components/homeComponents/qqqMy.vue'
},
{
    path: '/home/ttt',
    componentURL: '../src/components/homeComponents/qqqMy.vue'
}]
ary.forEach(item =>{ 
    router.addRoute('home', //当前路由的父路由的name, 如果该路由有name,并且名字与之相同,则会覆盖它
        {
        path: item.path,
        component: obj[item.componentURL]
    })
})

router.addRoute({
    path: '*',
    redirect: '/home'
})

$router 和 $route的区别

$router是vue router路由组件的实例对象,一般用来调用方法push, replace, go, back, addRoute
$route是路由参数对象

路由知识补充

路由组件与非路由组件的区别

1.路由组件一般放在pages/views文件夹下面,非路由组件一般放在components 文件夹下面
2.路由组件一般需要在router文件夹中注册(使用的即为组件的名字),非路由组件在使用的时候,是以标签的形式
3.在跟组件new Vue的时候往vue里面注册router,会使得组件里面可以访问到$router 和 $route
$route一般获取路由信息【path, params, query等】
r o u t e r 一般进行编程式导航时进行路由跳转【 p u s h , r e p l a c e 】 4. 注册完路由,不管路由组件还是非路由组件,身上都有 router一般进行编程式导航时进行路由跳转【push, replace】 4.注册完路由,不管路由组件还是非路由组件,身上都有 router一般进行编程式导航时进行路由跳转【pushreplace4.注册完路由,不管路由组件还是非路由组件,身上都有route和$router属性

路由的跳转

路由的跳转有两种方式
声明式导航router-link, 可以进行路由的跳转
编程式导航push/replace, 可以进行路由的跳转

编程式导航:声明式导航能做的,编程式导航都能做
但是编程式导航除了可以路由跳转,还可以做一些其他的业务逻辑

声明式导航:务必要有to属性

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值