天天看点

【Vue2】一文弄懂前端路由

一、对路由的理解

1.什么是路由

路由其实就是一组键值对or映射关系,在一个路由中应包含最基本的路径和组件信息。

示例如下:

【Vue2】一文弄懂前端路由

上面展示的是一个路由组,即用" [ ] "将一组路由写在一起,其中一个大括号中包裹的就是一个路由的信息,此处展示的是一个命名路由,因此多了一个name属性。

2.为什么需要路由

以往的写法是写多个html页面使用 <a> 标签进行跳转,但是有时一个页面只有部分内容需要替换or改变,此时再使用多页面跳转会有窗口抖动的感觉。

如上,展示的是淘宝特价版网页端,其左边选择不同品牌,右边数据会发生改变,这样的就可以使用路由。当网址路径发生改变时,相应组件就会展现。

【Vue2】一文弄懂前端路由

二、路由的基本使用步骤

1.准备工作

  • 安装路由插件库(注意版本对应问题,Vue2对应的插件库是3版本,但是目前默认安装最新版本)
  • 【Vue2】一文弄懂前端路由
  • 在main.js中引入并应用路由插件库,
  • 【Vue2】一文弄懂前端路由
  • 配置router路由器文件夹

(1)文件夹结构如下:

【Vue2】一文弄懂前端路由

创建了一个router文件夹,并配置一个index.js文件。

(2)index.js中具体内容如下:

【Vue2】一文弄懂前端路由

此处采用的是默认暴露,routes表示配置一组路由对象

  • 在main.js中引入路由器并绑定到Vue
【Vue2】一文弄懂前端路由

下面以一个案例来具体讲解后续工作

【Vue2】一文弄懂前端路由

2.替换工作

(1)创建路由组件

先说什么是路由组件,路由组件其实就是原本应该写成多个html中的内容,将它们写成组件形式,然后写到路由表中。

为了和普通组件区别,一般会另外用一个名为pages的文件夹存放路由组件,如下:

【Vue2】一文弄懂前端路由

其中,在components中存储的是一般组件,而在pages中存储的是路由组件。

(2)使用路由组件

那么在哪里使用路由组件呢?

这取决于你需要在哪里使用它,在哪个组件中需要展示该组件的区域效果,就在哪个组件中使用。

下面是一般组件和路由组件在App.vue中的使用区别

  • 一般组件直接写成组件名标签形式
  • 一般组件需要在使用它的组件中先①引入②注册,但路由组件则不用
  • 路由组件则要先用router-link将路由组件名包裹起来(此处只是a标签用router-link,若其他标签不同,则后续补充)
  • 且路由组件后面要使用 to="路径"的形式来指示具体要跳转的路由位置,这里的路径与router文件夹下配置的路由表中各路由的path属性值 保持一致
【Vue2】一文弄懂前端路由

注意!上面标签只是相当于<a>标签,具体呈现组件内容,还需要使用标签

(这里的router-view的位置才是真正呈现的地方)

【Vue2】一文弄懂前端路由

细节补充

  • 当路由组件被切换时,其实该路由对象是被销毁了,而每次点击其标签时,才会再去挂载
  • 不同组件对象上的router属性却是同一个。即整个应用只有一个router属性获取

三、路由进阶

1.嵌套路由

(1)什么是嵌套路由

嵌套路由 又称 多级路由,是在一级路由(即第一个被嵌套的路由)的基础上嵌套一层路由。为了嵌套的页面而出现的一种写法。

(2)怎么写嵌套路由

基本写法和一级路由差不多,另外注意以下几点即可

  1. 嵌套路由在创建路由时,是在其嵌套的一级路由下,用children:[…]包裹着的。如下:
【Vue2】一文弄懂前端路由
  1. 在标签中,嵌套路由的路径要带上父路由路径。如下:
【Vue2】一文弄懂前端路由

2.路由参数(父组件向子路由传递参数)

为什么需要传递路由参数

因为根据不同的点击,要显示不同的页面,而随着点击的链接不同,有时会有向子路由传递不同参数的需求(即路由界面需要接收参数,而不是静态页面)。

传递参数的方式

  • 利用路由的query参数
  • 利用路由的params参数
  • 路由的props配置

下面逐一介绍三种方式:

(1)query参数

query参数是路由对象的一个参数,可以使用console.log(this.$route)检验,如下:

【Vue2】一文弄懂前端路由

下面以Message组件向Detail组件传参为例,说明如何传递query参数,以及一些知识点。

【Vue2】一文弄懂前端路由

在Message组件(参数传递方)中

先准备好要传递的数据,也可以从数据库中获取。

【Vue2】一文弄懂前端路由

然后传递时,有以下两种写法:

  1. to的字符串写法

①to前面要加上冒号,表示后面双引号中要当成JS解析

②双引号内的内容要用反单引号括起来,这是ES6的一种技术,表示模板字符串

③参数要在路径后加 ? 然后指明参数属性,再用 ${ 参数 } 携带参数值,多个参数之间用 & 连接

【Vue2】一文弄懂前端路由
  1. to的对象写法

①to前面要加上冒号,表示后面双引号中要当成JS解析

②双引号内的内容写成一个对象,用大括号包住

③将要传递的query参数也写成一个对象,以键值对的形式(更清晰

【Vue2】一文弄懂前端路由

在Detail组件(参数接收方)中

想要应用参数 只需要在模板中获取$route中的query参数携带的数据即可。

【Vue2】一文弄懂前端路由

(2)params参数

params参数同样也是路由对象的一个参数。因此其参数接收方和query参数相同,但与query不同的是其参数发送方不同。

下面主要介绍其参数发送方(依然用Message组件举例)

传递时,同样有以下两种写法(但与query参数传递略有不同):

  1. to的字符串写法

①to前面要加上冒号,表示后面双引号中要当成JS解析

②双引号内的内容要用反单引号括起来,这是ES6的一种技术,表示模板字符串

③【不同之处】参数之间放在路径后,加 / 即可。无需指明参数属性名,只需用 ${ 参数 } 携带参数值,多个参数之间还是用 / 连接

【Vue2】一文弄懂前端路由

④【不同之处】由于第③步没有指明参数属性名,所以在router/index.js文件中要修改路径path值,指出相应位置的参数名来起到占位的作用

【Vue2】一文弄懂前端路由
  1. to的对象写法

①to前面要加上冒号,表示后面双引号中要当成JS解析

②双引号内的内容写成一个对象,用大括号包住

③将要传递的parmas参数也写成一个对象,以键值对的形式(更清晰

④【不同之处】将参数接收处(注意不是应用处)的path去掉(注意!不要把index.js文件中的路由路径去掉了啊),添加name属性(因为params参数只能使用name

【Vue2】一文弄懂前端路由

并且要在router/index.js文件中给传递参数方添加name属性 【这叫做命名路由,此后可以直接用名字代替路径】

【Vue2】一文弄懂前端路由

在Detail组件(参数接收方)中

想要应用参数 只需要在模板中获取$route中的params参数携带的数据即可。

【Vue2】一文弄懂前端路由

3.路由的props配置

为什么需要路由的props配置

  1. 因为在接收参数方组件中,直接在模板中使用参数太过复杂,于是试图将其简化,从而更简洁地使用。如下:
【Vue2】一文弄懂前端路由
  1. 使用计算属性可以达到简化模板中参数使用的效果,但是计算属性写起来又变繁杂了。如下:
【Vue2】一文弄懂前端路由

于是,就可以使用路由的props配置来一次传递多个参数,从简化模板中参数的书写。而路由的props配置主要有三种方法,下面将逐一介绍(均是从Message组件向Detail组件传递参数)

(1)值为对象

将props以对象形式写在参数发送方的路由中。缺点是:参数是静态写死的

【Vue2】一文弄懂前端路由

在参数接收方的组件中,添加props属性,并添加参数的key

【Vue2】一文弄懂前端路由

(2)值为布尔值

在参数发送方的路由中,添加一个props属性,值为true。缺点是:只能传递params参数,不能传递query参数

【Vue2】一文弄懂前端路由

在参数接收方的组件中,添加props属性,并添加参数的key

【Vue2】一文弄懂前端路由

这种方法只能传递params参数,所以在参数传递的方法上,要配置params参数的传递环境,如命名路由、路由路径设置、应用参数等等

(3)值为函数

在参数发送方的路由中,添加一个props函数,其形参默认就是$route,可以按照以下方式配置参数。

【Vue2】一文弄懂前端路由

(补充:也可以利用ES6中的解构赋值来简化return语句书写,详细见链接 Js连续解构赋值)

在参数接收方的组件中,添加props属性,并添加参数的key

【Vue2】一文弄懂前端路由

最后,注意一个问题,我刚刚上面丢了一个东西,见下图:

在标签内,除了参数,别忘了文本内容,否则没有可点击跳转信息了

【Vue2】一文弄懂前端路由

4.小结——参数传递时的位置关系

【Vue2】一文弄懂前端路由

在父子组件中,参数传递主要涉及以上三个部分中的四个位置,下面会逐一解释各个位置的作用。

①:参数的传递方(也就是这里涉及to的两种写法

②:参数的展示位置

③:参数的应用方or参数的接收方

④:进行props配置,以及与params参数相关的地方小补充:

【Vue2】一文弄懂前端路由

5.编程式路由导航

为什么需要编程式路由导航

其实这是为了不被给局限住,前面演示的<router-link> 只是为了替代点击标签<a>,而编程式路由导航使得任意元素都可以实现路由跳转,可以是按钮,也可以是图片等。

如何使用编程式路由导航

很简单,它可以在任何位置,且不需要用特殊标签包裹,只要绑定一个点击事件即可

【Vue2】一文弄懂前端路由

然后添加一个methods属性,配置相应的方法,如下图所示:

【Vue2】一文弄懂前端路由

但是这里涉及两个API,分别是push({ })和replace({ }),其内容均和的to的对象写法相同。

这里说明一下:

push() 和 replace()其实是两个与历史记录不同存储方式有关的API,其中push()方法是路由跳转时默认的属性,它会将历史记录进行压栈操作,所以可以自由前进后退。而replace()则会用当前页面记录覆盖前一条记录。

补充知识点——三个与跳转有关的API

【Vue2】一文弄懂前端路由

6.缓存路由

为什么需要缓存路由

因为路由组件在切换时会自动销毁,而有时会需要用户输入一些输入,此时如果切换组件,那么已经输入的数据就会丢失,所以需要对路由进行缓存,这样当组件被切换时就不会走销毁流程,避免不好的体验。

如何使用缓存路由

【Vue2】一文弄懂前端路由

如上图所示,只需要用keep-alive标签将router-view包裹起来即可,这样在此处展示的组件都会被缓存(此处是News组件和Message组件,都被缓存)

那么如果只想缓存某个组件怎么办?

答:添加include属性,其值为要缓存的组件名。如下:

【Vue2】一文弄懂前端路由

如果要缓存多个,但不是全部怎么办?

答:在include前添加冒号,并将值写成数组形式

【Vue2】一文弄懂前端路由

7.两个路由组件独有的生命周期钩子

beforeDestroy() {
            console.log('News组件即将被销毁了')
            clearInterval(this.timer)
        },
mounted() {
    //设置一个定时器
    this.timer = setInterval(()=>{
        this.opacity -=0.01
        if(this.opacity <= 0) this.opacity = 1      
    },16)
},      
//下面两个是路由组件特有的生命周期钩子,切换到当前组件时actived被触发
        //激活时触发
        activated() {
            //设置一个定时器
            this.timer = setInterval(()=>{
                this.opacity -=0.01
                if(this.opacity <= 0) this.opacity = 1      
            },16)
        },
        //失活时触发
        deactivated() {
            console.log('News组件即将被销毁了')
            clearInterval(this.timer)
        },      

继续阅读