四、Vue之路由详解

一、简介

Vue项目采用的是单页面应该(SPA),即整个应用只有一个页面,通过路由来在单页面中进行组件的切换,从而改变页面展示的内容,而不发生页面的跳转。

二、路由的使用

2.1 安装插件
路由是一个插件,首先要安装插件。默认安装的是vue-router4版本,对应的是vue3版本。这里使用vue2,所以要指定版本安装,安装vue-router3版本。

npm i vue-router@3

安装成功后,可以在package.json文件里看安装版本:
四、Vue之路由详解_第1张图片
2.2 定义路由路径
在src下创建router文件夹,定义index.js,里面配置路由映射路径:

//该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'

//引入组件,这里引入需要配置跳转路径的组件,这种组件也称为路由组件
import HelloWorld from './components/HelloWorld.vue';
import HelloHello from './components/Demo.vue';

//创建一个路由器对象
const router= new VueRouter({
    routes:[//配置路由规则
        {
            path:'/HelloWorld', //组件的跳转路径
            component:HelloWorld  //要跳转的组件
        },
        {
            path: '/HelloHello',
            component: HelloHello
        }
    ]
})

//暴露路由器的对象
export  default router;

2.3 Vue实例引入路由器
在main.js中,引入VueRouter和上述定义的router对象

//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'

使用router插件:

Vue.use(VueRouter)

使用该插件后,Vue对象中,就可以定义router属性了,然后把暴露出来的router对象传进去。

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	router:router
})

2.4使用路由实现组件跳转切换
在切换组件的按钮处,用标签包裹,to属性写index.js里配置的路由路径。实现点击内容,切换组件的效果,如下:

<router-link to="/HelloWorld">Hello</router-link><br>
<router-link to="/HelloHello">Demo</router-link>

在展示内容区域,用占位,会自动在该区域展示组件内容:

 <router-view></router-view>

注意:一般称定义在中的组件为路由组件。一般把路由组件都放在pages文件夹下。非路由组件放在components文件夹下。

2.5 知识升华
当使用vue-router插件后,所有的组件实例里,包括路由组件和非路由组件,都会有$router属性和$route属性。
$route属性每个组件都存着自己组件的路由信息,每个组件各不相同,如下图:
四、Vue之路由详解_第2张图片
里面有fullPath属性,meta属性,params属性和query属性等多个属性。
$router属性全局都是一个同样的对象,它就是管理路由的路由器对象。
四、Vue之路由详解_第3张图片
切换组件时,默认情况下,每次被切换的组件都会被销毁,重新切换回该组件时,再重新创建该组件。

三、多级路由

当路由组件内部,也要切换路由时,可以在路由文件中配置多级路由。配置规则如下:
四、Vue之路由详解_第4张图片
跳转路径时,从父级路径开始写全路径:

<router-link to="/home/news">News</router-link>

四、路由传参

上面讲到,在每个组件的$route属性中,都有query属性和params属性,这两个属性是用于在组件跳转时,携带参数,给跳转到的组件传递数据用的。
4.1 query传参
第一种写法:
的to属性中,在路由路径后面直接加?,然后拼接key=value&key=value传递参数,类似于get请求传参。当传递的参数用到组件中的数据时,需要在to前面加:,相当于v-bind的简写。但是加了冒号后,to里面的全部内容都会当成js表达式来解析,而url的路径不是js表达式,这么写肯定会报错。所以需要用分隔符`来包裹url数据,然后用${}来获取组件中的数据,写法如下:
在这里插入图片描述
这样,切换到的组件的route属性的query里面,就有router-link中传递过来的参数了。
四、Vue之路由详解_第5张图片
第二种写法:
router-link标签的to属性,写成对象的形式,如下:
四、Vue之路由详解_第6张图片
写成对象的形式,path属性写路由的路径,query属性写传参。除了使用path属性外,还可以定义name属性,来与路由组件进行映射,此时,index.js的路由配置里也要写name属性。
需要注意的是,to属性写成对象后,query里的参数就无需写占位符了,直接写组件属性即可。
接收到数据后,vc实例就可以通过route.query.xxx来获取值了。

4.2 params传参
使用params传递参数,类似于resultful风格的url进行参数传递。
首先,在router/index.js里的路由路径里,写参数占位符,如下:
四、Vue之路由详解_第7张图片

中传参时,用RestFul风格传参。如下:
四、Vue之路由详解_第8张图片
注意:给params传参时,to属性里写成对象时,必须用name属性映射路由,不能用path属性映射

切换到组件后,组件的$route.params里就有参数了。
props属性
在配置params传参的配置文件中,可以配置props属性,这样,在接收参数的组件中,通过props属性就可以直接调用参数属性获取值了,无需再写复杂的route.params获取参数了,props配置如下:
四、Vue之路由详解_第9张图片

五、路由的其他特性

5.1 的replace属性
当路由组件进行切换时,浏览器默认把上一个组件当成了历史记录,点返回键,会调到上一个切换的组件页面,称之为push模式。如果不想跳到上一个组件中,那么把该组件的router-link的属性设置为true。浏览器就不会记录这个地址,也不会返回这个组件,而是返回上一个replace为false的组件中去。
四、Vue之路由详解_第10张图片

5.2 编程式路由
所谓编程式路由,就是不通过router-link标签进行组件的切换,而是通过代码方式进行组件切换。
四、Vue之路由详解_第11张图片

5.3 缓存路由组件
上面讲到,当切换组件时,被切换的组件会被销毁,每次切换,都涉及到组件的销毁和重新创建,如果不想让组件重新销毁,比如用户在组件中输入了一些数据,等切换回来时,这些数据还要在页面保留,那么就不能进行销毁。
需要进行特殊的设置,即在占位符处,用标签包裹。用include属性设置不被销毁的组件,写组件name属性。
一个组件时:
在这里插入图片描述
多个组件时:
在这里插入图片描述

5.4路由组件独有的两个生命周期
路由组件有两个新的生命周期,
activated:路由组件被激活时触发
deactivated:路由组件失活时触发。

5.5 路由的meta属性
在路由配置文件index.js中配置路由时,可以设置meta属性,来自定义一些信息。通常自定义一些标识信息,然后在路由守卫中,获取这些标识,进而判断是否放行等操作。
5.6 路由的hash模式和history模式
路由配置中,可以配置mode属性,默认是hash模式,这种模式下,浏览器的地址栏中,会有#。#后面的路径,都是vue项目内部跳转的路径,其不会传到服务器后台,#及#后面的路径,称之为hash路径。
mode属性可以设置为history,这样,浏览器地址栏中就没有#了。这种模式的弊端是,vue内部跳转的路径,也会发送给服务器后台,这样就会造成后台服务器返回404错误,因为vue内部跳转的路径,后台服务解析。这就需要后台服务进行一些处理了。

六、路由守卫

相当于访问某个路由组件时,给路由组件加了一个拦截器,这个拦截器就叫守卫。
全局前置守卫
在访问每个路由前,执行的一段代码,写法如下:
在router/index.js里,定义完router对象后,定义beforeEach函数:

// 前置路由守卫(路由导航)
router.beforeEach((to, from, next) => {
     console.log('to:', to)
     console.log('from:', from)
    if (to.path == '/home') {
        console.log('做逻辑判断')
    }
    // 下方这个next是适配所有路由的,放行操作,如果没有next,则会卡住,不会跳转进路由组件
    next()
})

beforeEach函数的调用时机:初始化时调用一次,以及每次路由切换时,调用一次。
全局后置守卫
在router/index.js里定义完router对象后,调用afterEach函数,定义全局后置守卫:

// 进入路由后方法勾子
router.afterEach((to, from) => {
    console.log(to, '后置第一个参数')
    console.log(from, '后置第二个参数')
    /*
      to 目标路由
      from 源路由
    */
    if (to.meta.title) {
        console.log(to.meta.title);
    } else {
        console.log('暂无名称');
    }
});

调用时机:初始化时调用一次,以及每个路由切换后,调用一次。
后置全局路由不用放行,没有next参数。

独享守卫
写在路由配置文件的某个组件内,而不是写在router定义完后。与前置守卫类似,但是只拦截某一个路由。

{
            path: '/HelloHello',
            component: HelloHello,
            beforeEnter(to,from,next){
                if(to.path==="/test"){
                    alert("请登录");
                    next(false); // 禁止跳转
                }else{
                    next()
                }
            }
        }

独享守卫只有前置拦截,没有后置拦截。

组件内守卫
不在路由的js里写,而在组件内部写的路由,包括beforeRounterEnter和beforeRouterLeave属性
通过路由规则,进入该组件时调用和通过路由规则,离开该组件时被调用。
与上述讲到的activated和deactivated类似,不同的是,组件内守卫必须通过路由规则进入时才会进入beforeRounterEnter和beforeRouterLeave,而直接写组件标签调用的方式进入组件不会走这两个方法。

你可能感兴趣的:(vue,vue.js,前端,javascript)