前端框架Vue自学之Vue router(六)

摘要:
正文:Vuerouter一、认识路由1、路由就是通过互联的网络把信息从源地址传输到目的地址的活动。为了演示改变url,却不让页面整体刷新,我们先用vueCLI2创建工程,然后记得选择安装vue-router。此外,HTML5的history模式:pushState也可以修改url却不刷新网页。修改的url显示的是最新push进去的修改项(栈顶)。对应的弹出栈顶方法是history.back(),同样也是修改了url却不刷新页面。

终极目标:掌握和使用Vue(全家桶:Core+Vue-router+Vuex)

本博客目的:记录Vue学习的进度和心得(Vue router)

内容:学习和使用Vue router。

正文:

Vue router

一、认识路由

1、路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动。

2、路由器提供了两种机制:路由转送。路由是决定数据包从来源到目的地的路径。转送将输入端的数据转移到合适的输出端。

3、路由中有一个非常重要的概念叫路由表。路由表本质上就是一个映射表,决定了数据包的指向。

二、前端渲染后端渲染和前端路由后端路由

1、后端渲染和后端路由

以前的网页开发整个HTML页面是由服务器来渲染的,即后端渲染,通过使用JSP(Java server page)/PHP/ASP语言开发的。以JSP为例,当我们在浏览器输入一个网址(url)时,把浏览器会发这个网址(url)给服务器,服务器首先会解析这个网页,在后台就会通过JSP技术(Controller)把网页写好,这个网页包含HTML和CSS和一些Java代码,Java代码的作用是从数据库中读取数据,并且将它动态地放在页面中(把数据动态渲染这个页面)。最后服务器直接将渲染好的网页发送给浏览器(这个网页只有HTML+CSS)(完成了一个IO操作)。这就是后端渲染(网页是在服务器端渲染的)。

可以发现,在后端渲染这种模式下,我们每输入一次url,服务器就会根据这个url在后端渲染网页,然后传到浏览器中。一个url(路径)对应(映射)一个网页,这个映射关系是服务器管理的。因此后端处理URL和页面之间的映射关系叫做后端路由

优点:这种情况下渲染好的页面,不需要单独加载任何的JS和CSS,可以直接交给浏览器展示,这样也有利于SEO(搜索引擎优化)的优化。

缺点:整个页面的模块由后端人员来编写和维护(例如Java数据库)。前端开发人员如果要开发页面,需要通过PHP和Java等语言来编写页面代码。而且通常情况下HTML代码和数据以及对于的逻辑会混在一起,编写和维护都是非常糟糕的事情。

2、前后端分离和前端渲染

网页开发的第二个阶段是前后端分离阶段。随着Ajax(异步 JavaScript 和 XML)的出现,有了前后端分离的开发模式。后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中。

其过程大致是这样:后端是一个服务器(提供API接口的服务),服务器连接数据库;前端在浏览器开发;中间还有一个静态资源服务器(当然有的公司会把后端服务器和静态资源服务器合在一起)。当我们在浏览器输入网站(url),接着会从静态资源服务器获取HTML+CSS+JS代码等静态资源,HTML+CSS是可以在浏览器直接渲染,JS代码时由浏览器执行,一般JS里面会有API请求,通过Ajax技术,然后向后端服务器请求数据,后端服务器将对于的数据返回给浏览器,这些数据会通过其他的JS代码,在浏览器创建HTML元素,并把数据插入其中,最后在渲染整个页面。

浏览器中显示的网页中的大部分内容,都是由前端写的JS代码在浏览器中执行,最终渲染出来的网页。这就是前端渲染

这样做最大的优点就是前后端责任的清晰,后端专注于数据上,前端专注于交互和可视化上。并且当移动到(IOS、Android)出现后,后端不需要进行任何处理,依然使用之前的一套API即可(因为用的是API接口,不管是浏览器,还是移动端,接口对应上即可使用相关服务)。目前很多的网站依然采用这种模式开发。

3、前端路由

网页开发的第三个阶段是单页面富应用SPA(Single Page Application)阶段。其实SPA最主要的特点就是在前后端分离的基础上加上一层前端路由,也就是前端来维护一套路由规则。

SPA,整个网页只有一个HTML页面。之前在前后端分离的时候,静态资源服务器是一个网址(url)对应一套HTML+CSS+JS,而在SPA中, 静态资源服务器只有一套index.html+css+JS。即在SPA中,在浏览器输入网页时,浏览器先从静态服务器获取HTML+CSS+JS(全部资源)但并非直接执行。但我们点击这个网址(相当于打开另一url),然后会从HTML+CSS+JS(全部资源)中抽离要在这个url显示的东西。这时,不同的url中,通过在同一套HTML+CSS+JS(全部资源)中进行抽离,可以显示不同url对应的页面信息,这种映射关系就是前端路由。(之前不同的url会向静态资源服务器请求一套HTML+CSS+JS资源,前端路由不会向静态资源服务器请求,而是通过一些JS代码判断,将从同一套HTML+CSS+JS(全部资源)中抽取一部分资源,其实在vue中就是一个个组件,然后在对应不同的url的页面中渲染显示)

前端路由就是从不同url在同一套HTML+CSS+JS(全部资源)所对应的不同组件(页面)资源的映射关系,这个关系是前端在管理的。  

4、url的hash和HTML5的history

前端路由的核心是改变url,但是页面不进行整体的刷新。那怎么做到呢?一个是使用url的hash,一个是使用HTML5的history(的很多模式)。

url的hash,也就是锚点(#),本质上是改变window.location的href属性。我们可以直接通过直接赋值location.hash来改变herf,但是页面不发生刷新。

为了演示改变url,却不让页面整体刷新,我们先用vue CLI2创建工程,然后记得选择安装vue-router。然后运行调试(npm run dev),打开页面和控制台,发现一开始会加载一些资源(为了方便看是否刷新,可以将Network的clear按钮点击(红色圆旁边那个禁止图标))。

前端框架Vue自学之Vue router(六)第1张

当在控制台Console中通过url的hash修改url时(location.hash = 'aaa'),发现页面没有刷新。

前端框架Vue自学之Vue router(六)第2张(url修改前)

前端框架Vue自学之Vue router(六)第3张(修改url的hash)

前端框架Vue自学之Vue router(六)第4张(修改url后)

前端框架Vue自学之Vue router(六)第5张(network没有请求资源)

此外,HTML5的history模式:pushState 也可以修改url却不刷新网页。

前端框架Vue自学之Vue router(六)第6张(在console通过history修改url)

前端框架Vue自学之Vue router(六)第7张(修改了url,但network没有请求资源,即页面没刷新)

注意history.pushState是一个栈结构(后进先出)。修改的url显示的是最新push进去的修改项(栈顶)。

前端框架Vue自学之Vue router(六)第8张(压入新url)前端框架Vue自学之Vue router(六)第9张(显示栈顶)

对应的弹出栈顶方法是history.back(),同样也是修改了url却不刷新页面。可以发现此时用这两种方法是可以在浏览器的返回/前进按钮(一般是浏览器左上角的两个箭头按钮)是可以使用的(因为是栈)。history.back()相当于返回,而histor.forward()相当于前进。(注意,url中出现了#,即hash模式,是因为我们之前项目的代码中,默认的路由实例模式是hash模式,如果修改为history的mode就不会出现#,后面会说第三章第5小节有讲)

前端框架Vue自学之Vue router(六)第10张(弹出)前端框架Vue自学之Vue router(六)第11张(显示栈顶)

HTML5的history模式:replaceState。同样可以修改url却不刷新页面,但没有返回按钮可以使用(因为是代替)。

前端框架Vue自学之Vue router(六)第12张(用法)前端框架Vue自学之Vue router(六)第13张(修改了url,没刷新页面,但没有返回按钮可以使用)

HTML5的history模式:go。history.back()相当于history.go(-1),而histor.forward()相当于history.go(1)。go里面的参数可以是-2 等,相当于执行history.back()两次。上述三个方法等同于浏览器的前进后退。

总结:以后在配置路由时,就有两种方式:hash方式和history方式。 

三、Vue-router

1、前端框架的前端路由

目前前端流行的三大框架,都有自己的路由实现。如Angular的ngRouter,React的ReactRouter,Vue的Vue-router。

2、认识vue-router

vue-router是vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。

vue-router是基于路由和组件的。路由用于设定访问路径,将路径和组件映射起来。在vue-router的单页面应用中,页面的路径的改变就是组件的切换。

3、vue-router的安装和使用

因为之前我们学习了webpack(在我前一个博客),后续开发中我们主要是通过工程化的方式进行开发的。所有在后续,我们直接使用npm来安装路由即可。

步骤一:安装vue-router(npm install vue-router --save)(运行时依赖)。如果是之前通过vueCLI创建项目的时候,选择安装的了vue-router,可以在package.json文件可以看到vue-router,并且在src会自动创建router文件夹和一个关于路由的index.js(下面也会讲到手动安装和时候vue-router,不慌)。

前端框架Vue自学之Vue router(六)第14张

步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过vue.use()来安装路由功能)。首先,导入路由对象,并且调用Vue.use(VueRouter)。接着,创建路由实例,并且传入路由映射配置。最后,在vue实例中挂载创建的路由实例。

如果我们通过vueCLI创建项目的时候,没有选择安装vue-router,也可以手动安装上面两个步骤安装使用。

大致流程:安装vue-router。终端输入npm install vue-router --save。使用vue-router。首先,在src文件夹下创建名为router的文件夹,用来放置我们路由配置的相关信息。接着,在router文件夹下创建index.js文件,配置路由信息,其中,导入VueRouter,调用Vue.use()方法安装VueRouter插件,由于这个是vue方法,需要导入vue,接着,创建VueRouter对象,并在这个对象中传入路由映射配置,并将其导出,供vue实例挂载。

前端框架Vue自学之Vue router(六)第15张(router文件夹下的index.js)

最后一步是在main.js里面导入router,并在vue实例挂载。这样就可以使用router了。

前端框架Vue自学之Vue router(六)第16张(main.js)

4、路由映射配置和呈现出来

使用vue-router的步骤:首先,创建路由组件。接着,配置路由映射:组件和路径映射关系。最后,使用路由:通过<router-link>和<router-view>。

大致操作过程:

第一步,在src文件夹下,创建组件,例如创建两个组件About.vue和Home.vue。

前端框架Vue自学之Vue router(六)第17张(About.vue)前端框架Vue自学之Vue router(六)第18张(Home.vue)

第二步,然后在router的index.js文件进行映射配置,一个映射是一个对象,对象中包含两个属性:path和component(这样就把路径和组件对应起来了),接着导入组件,把组件放置在映射对象的component属性中,所以这里我们配置两个对象。注意,path是相对路径,而不是url(url是协议头://host/query等)。

前端框架Vue自学之Vue router(六)第19张(router文件夹的index.js文件)

第三步,接着,使用路由。由于需要在同一个页面想显示两个不同路径下两个组件。所以我们得从App.vue修改(因为入口文件main.js导入的是App.vue,并将其用render函数渲染显示出来),添加两个标签按钮,通过按钮进行修改路径。所以,我们在App.vue的template标签内使用<router-link>标签(router-link是vue-route已经r注册的全局组件),并且<router-link>标签里面有个to属性,将to属性的属性值对应于我们之前映射关系的相对路径path,这样就可以和相对路径path的组件对应。(<router-link>标签最终渲染为<a>标签)

但此时只使用<router-link>标签只能修改url,而对应地址所映射的组件没有显示出来,此时,需要使用<router-view>标签。但注意,<router-view>所显示的组件的位置是可以调的,后续我们会学习如果让他在我们想要的位置上(利用框架),此外在路由切换时,切换的是<router-view>挂载的组件,其他内容是不会发生改变的。

前端框架Vue自学之Vue router(六)第20张(App.vue,<router-view>的位置会绝对组件显示的位置,例如组件显示在两个<router-link>标签的下面)

前端框架Vue自学之Vue router(六)第21张(此时点击首页对应的home相对路径了;点击关于对应about相对路径)

5、路由的默认值和修改为history模式

之前在默认情况下,进入网站的首页,我们希望<router-view>渲染首页的内容,但是在我们之前的实现中, 默认没有显示首页组件,必须要让用户点击才可以。

如何可以让路径默认跳到首页,并且<router-view>渲染首页组件呢?非常简单,我们只需要在路由配置多配置一个映射就可以了,即在routers多配置一个映射,path配置的是根路径:/或者为空,redirect是重定向,也就是我们将根路径重定向到/home的路径下,这样就可以得到我们想要的结果了。

前端框架Vue自学之Vue router(六)第22张(index.js添加重定向)

前端框架Vue自学之Vue router(六)第23张(没有点击首页,直接打开就是默认为首页,并渲染了组件)

在之前修改url的时候发现都是相对路径前面带有#,即是hash值模式(路由默认下是hash模式)。如果我们不想要这个#,可以使用HTML5的history。

我们在index.js中在VueRouter实例中,添加mode属性,并且值为history即可。

前端框架Vue自学之Vue router(六)第24张(index.js中的VueRouter实例)

前端框架Vue自学之Vue router(六)第25张(相对路径/home前面没有了#)

6、<router-link>的其他属性补充。

之前我们只使用了<router-link>的to属性,即点击这个link跳转到对应的相对路径。

<router-link>还有一些其他属性:

tag:tag可以指定<router-link>之后渲染成什么组件,比如之前写的<router-link>默认渲染为<a>,通过tag我们可以渲染为<button>等(<router-linkto='/home'tag='button'>首页</router-link>)。

replace:replace不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中(之前用的相当于是history.pushState,所以后退键可以使用)。用法:不需要写任何值,就replace即可(<router-linkto='/home'tag='button'replace>首页</router-link>)。

active-class:当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class,设置active-class可以修改默认的名称。或者是直接在router文件夹的index.js文件中的VueRouter实例中,使用linkActiveClass属性进行统一修改router-link-active的名称。在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类,但是通常不会修改类的属性,会直接使用默认的router-link-active即可。

7、通过代码跳转路由

如果我们想在别的标签,拥有使用<router-link>的跳转功能,可以通过代码的方式跳转路由。

例如,通过事件监听,定义方法和使用$router,获取router对象(这个router对象就是我们定义的VueRouter实例)的方式。在App.vue中创建两个button,并且监听事件,然后在脚本定义方法。this.$router相当于vue-router对象,其属性可以选为push(相当于history.pushState)或replace(相当于history.replaceState),但注意不能直接使用history方法,这样绕过了router了。

前端框架Vue自学之Vue router(六)第26张

8、vue-router的动态路由使用

在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望如下的路径:/user/aaa或/user/bbb,除了有前面的/user之外,后面还跟上了用户的ID。这种path和component的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)。

例如我们要创建用户的一些动态路由(例如/user路径后面能跟上一些用户的id的路径)。

实例大致过程:第一,先创建/user的路径。首先,在src/components下创建User.vue(组件),然后在/router下的index.js进行配置User路由对象(User相对路径和组件对象关系),最后是在App.vue用使用<router-link>和<router-view>引用User组件。这样就完成了/user的路由【第一大步骤之前在第4小节说过】

现在我们要想使用动态路由(例如/user路径后面能跟上一些用户的id的路径)。

假如我们想动态从脚本中的data数据获取userId(一个变量)。例如zhangsan。

前端框架Vue自学之Vue router(六)第27张(App.vue)

首先,修改index.js中的user组件配置。(:/变量名)

前端框架Vue自学之Vue router(六)第28张(修改前)前端框架Vue自学之Vue router(六)第29张(修改后)

接着在<router-link>中用v-bind:绑定to属性即可,往对应变量userID传data里面的值。

前端框架Vue自学之Vue router(六)第30张

此时,点击用户,url就可以动态变为user/userId,即user/zhangsan。

前端框架Vue自学之Vue router(六)第31张(点击用户)

进一步地,如果我们想根据userId,如zhangsan,获取他的一些信息,渲染到当前页面(而不是之前默认的user组件的原来的信息:我们是用户界面 我是用户的相关信息)。

我们可以使用$route(之前我们讲过$router是我们之前创建VueRouter实例对象,而这个是$route,是指的是VueRouter实例对象的routers(里面有很多个路由对象)中处于活跃active的对应的路由对象)。并且在User.vue组件中使用计算属性。

前端框架Vue自学之Vue router(六)第32张(user.vue)

此时,打开页面,点击用户。url后面有user/userId,<router-view>中的h2标签中的userId也被渲染出来了。

前端框架Vue自学之Vue router(六)第33张(点击用户)

同样地,此时如果App.vue中的data的userId改变了,变为lisi。最后页面的userId也会相应变化。

前端框架Vue自学之Vue router(六)第34张(App.vue)

前端框架Vue自学之Vue router(六)第35张(userId为lisi)

这就是动态路由。

9、打包文件的解析

路由的懒加载。当打包构建应用时,JavaScript包会变得非常大,影响页面加载(由于请求的资源过大,会在页面有暂时空白显示)。如果我们把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

在我们用vue CLI构建项目的时候,当打包的时候,就是把目标文件分为几个文件(而不是之前的一个bundle.js文件)。其中,js文件夹中,app.XX.js是当前应用程序开发的所有代码(业务代码),vendor.XX.js是vendor(提供商,第三方的东西:vue/vue-router/axios(网络请求框架)/bs(一种滚动框架)),manifest.xx.js是为了打包的代码做底层支持的(如导入导出,ES6转ES5等)。

注意,.map文件是js文件压缩后,文件的变量名替换对应、变量所在位置等元信息数据文件,一般这种文件和min.js主文件放在同一个目录下。 这样的好处就是说,在调试的时候,如果有一些JS报错,那么浏览器会通过解析这个map文件来重新merge压缩后的js,使开发者可以用未压缩前的代码来调试,这样会给我们带来很大的方便。

前端框架Vue自学之Vue router(六)第36张

路由懒加载的使用。懒加载,用到时再加载,相当于将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才加载对应的组件。

路由懒加载的方式有:

方式一:结合Vue的异步组件和Webpack的代码分析(不推荐)。const Home= resolve => { require.ensure(['../components/Home.vue'], () =>{ resolve(require('../components/Home.vue')) })};

方式二:ADM写法(不推荐)。 const About = resolve => require(['../components/About.vue'], resolve);

方式三:在ES6中,我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割(强推)。const Home = () => import('../components/Home.vue')

所以,我们重新在之前的路由配置代码(index.js)使用懒加载。首先,注释掉组件包的导入,然后用方式三的路由懒加载,然后在配置常亮routes中对应组件放置对应模块。

前端框架Vue自学之Vue router(六)第37张(index.js

此时,打包,可以发现打包的js文件夹内多个几个.js文件,即不同路由路径的js代码块。因为有三个组件,所以是0 1 2的js文件。

前端框架Vue自学之Vue router(六)第38张

10、路由的嵌套使用

嵌套路由(在路由里面嵌套另一个路由)是一个很常见的功能。比如在home页面中,我们希望通过/home/news和/home/message访问一些内容。一个路径映射一个组件,访问这两个路径也会分别渲染两个组件。即路径和组件的关系如下:

前端框架Vue自学之Vue router(六)第39张

实现嵌套路由有两个步骤:首先,创建对应的子组件,并且在路由映射中配置对应的子路由。接着,在组件内部使用<router-view>标签。

大致操作流程:首先,在src/components下创建子组件HomeNews.vue和HomeMessage.vue。接着,在router下的index.js中,在home组件的映射配置中配置其两个子组件(这才是嵌套嘛,通过利用children属性),并且也是使用懒加载。

前端框架Vue自学之Vue router(六)第40张

最后,在Home.vue(父组件)中使用使用组件的方法一样,使用<router-link>和<router-view>来显示我们的两个子组件。注意,<router-link>中的to属性得写完整的相对路径。

前端框架Vue自学之Vue router(六)第41张(Home.vue)

然后,运行调试,发现首页有了两个子组件路由,点击新闻或消息,页面会渲染其组件(子组件)。

前端框架Vue自学之Vue router(六)第42张(home页面)

前端框架Vue自学之Vue router(六)第43张(渲染子组件)

11、传递参数

有时候我们的使用路由,会把一些参数传递过去。(我们之前传递userId就属于一种参数传递)

传递参数主要有两种类型:paramsquery。使用方式:<router-link>的方式和JavaScript代码方式。

params的类型:配置路由格式:/router/:id ;传递方式:在path后面跟上对应的值;传递后形成的路径:/router/123,/router/abc 。

这个例子之前在第8小节有说。(通过$route.params.id)

query的类型:配置路由格式:/router,也就是普通配置;传递方式:对象中使用query的key作为传递方式;传递后形成的路径:/router?id=123, /router?id=abc。

为了演示传递参数(query类型),我们这里再创建一个组件,并且将其配置好。首先,创建新的组件Profile.vue;接着,配置路由映射;最后,添加跳转的<router-link>。

大致流程:src/components创建Profile.vue组件,接着在router/index.js配置路由(懒加载的方式),然后在App.vue中使用<router-link>。

前端框架Vue自学之Vue router(六)第44张(页面展示没有问题)

现在,我们想向Profile传递参数。首先我们在router-link中用v-bind绑定to属性,并使用对象把路由路径传入(这是方便我们后续传递参数的使用)。

前端框架Vue自学之Vue router(六)第45张

由于to绑定是一个对象,所以里面可以不止一个属性,我们可以写入我们的query。

前端框架Vue自学之Vue router(六)第46张

此时的页面,url路径把我们的query对象加载了。(注意是问号连接,这就是query方式拼接,查询)

前端框架Vue自学之Vue router(六)第47张

补充:统一资源定位符的标准格式如下:[协议类型]://[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID],一般是 协议://主机:端口//路径?查询(scheme://host:port/path?query#fragment)。

这个时候,如果我们想取出query对象,并渲染显示在页面上可以通过$route.query(在Profile.vue中)。query对象能取出来,对象的属性也是可以取出来的,如$route.query.name等。

前端框架Vue自学之Vue router(六)第48张(使用$route.query)

前端框架Vue自学之Vue router(六)第49张(页面显示query对象)

如果我们是想从别的HTML标签进行类似用组件路由的参数传递,可以使用监听事件和定义方法和this.$router.push或者replace(之前讲过啦)。

前端框架Vue自学之Vue router(六)第50张(App.vue中)

前端框架Vue自学之Vue router(六)第51张(添加方法)

前端框架Vue自学之Vue router(六)第52张(页面展示)

12、router和route由来

$router就是创建VueRouter的实例(即我们定义名为router的那个常量,vue-router源码实现的),通过打开VueRouter(VScode中按Ctrl+鼠标左键),发现里面有很多方法,例如push,replace。所以我们可以通过$router对象,使用这些方法(之前就是这么做的)。

前端框架Vue自学之Vue router(六)第53张(index.js)

前端框架Vue自学之Vue router(六)第54张(点开VueRouter)

$route是当前处于活跃的路由,即页面渲染的路由(也是vue-router源码实现的)。

补充1:所有的组件都继承自Vue类的原型

补充2:之前讲过,使用一个plugin即插件,如VueRouter,要先Vue.use(ueRouter),其会执行ueRouter.install。所以如果我们想看VueRouter(vue-router)的源码,GitHub下载(注意是从node_modules看版本哦),然后打开其install.js开始看。会发现install.js里面有用Vue.component()全局注册了RouterView和RouterLink组件(也就是我们之前使用的<router-view>,<router-link>)。

13、全局导航守卫

当我们在进行路由跳转的时候,我们想监听跳转过程,从而进行一些操作,这就是导航守卫。

我们来考虑一个需求:在一个SPA应用中,如何改变网页的标题呢?网页标题是通过<title>来显示的,但是SPA只有一个固定的HTML,切换不同的页面时,标题并不会改变。但是我们可以通过JavaScript来修改<title>的内容,window.document.title='新的标题'。那么在Vue项目中,在哪里修改?什么时候修改比较合适呢?

利用vue的生命周期函数。create()创建出组件时回调的,mounted()我们的template挂载到整个DOM时回调的,updated()整个界面发生刷新时回调的。

所以导航守卫可以第一种写法:把create(){document.title='对应标题'}放入每个跳转路由的组件内。

但是这样写很累赘,每次有新组件如果需要这个功能,则都要加上,很麻烦。

可以发现,其本质是路由跳转,我们只需监听路由跳转,当路由跳转了,就修改对应的document.title即可。这就是全局导航守卫(监听全局的跳转)。

大致流程:首先在router/index.js中,对路由实例使用beforeEach()函数(它会在路由即将改变前触发(即前置钩子/前置守卫),对应的还有afterEach()),这个函数看源码:

前端框架Vue自学之Vue router(六)第55张(打开beforeEach())

前端框架Vue自学之Vue router(六)第56张(打开NavigationGuard)

即路由的beforeEach()里面需要一个函数,里面包含三个参数:to,from,next。(其中next方法必须使用,否则无法路由跳转,因为原来内部beforeEach()是使用next(),当我们使用这个beforeEach()会把原来的beforeEach()覆盖的)注意,源码中,to和from都是Route类型,代表着从from跳转到to。

所以我们在index.js中的所有路由中加上一个meta元数据对象,里面放置对应的title。(元数据:描述数据的数据)

前端框架Vue自学之Vue router(六)第57张(home配置路由中加入meta,其他配置路由也是一样)

最后在index.js中,使用beforeEach()方法。

前端框架Vue自学之Vue router(六)第58张

然后当我们点击首页时,页面标题显示‘首页’。点击关于,页面标题显示‘关于’

前端框架Vue自学之Vue router(六)第59张(点击 首页)

但是,当我们点击首页的子组件的时候,发现没有显示标题,例如此时我们点击‘新闻’。

前端框架Vue自学之Vue router(六)第60张(点击‘新闻’,标题是undefined)

这是因为子组件之前使用了路由嵌套。相当于此时我们获取的to属性是不同与父组件的,即没有meta,所以我们修改为:

document.title=to.matched[0].meta.title; 获取父组件的meta。此时就可以了。
前端框架Vue自学之Vue router(六)第61张(点击‘新闻’ 显示title)

补充1:刚才讲的是前置钩子(beforeEach()),如果是后置钩子,即afterEach,不需要主动调用next()函数(源码里也是说不需要的,因为表示的是路由跳转完了)。

补充2:前置钩子/前置守卫 和后置钩子都称之为全局守卫。除了全局守卫,还有路由独享的守卫组件内的守卫。进一步了解可以看官网:VueRouter的导航守卫

14、vue-router keep-alive及其他问题

keep-alive是vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。例如,当我们点击渲染到某个A组件时,假设A组件里有两个子组件A1和A2,当点击A组件默认是先渲染A1时,我们再点击A2,当然此时渲染到A2。此时如果我们点击另一个路由,到B组件,再点击回A组件,此时,A组件中还是先渲染A1而不是我们之前最后操作的A2。原因是点击A组件时相当于Vue生命周期的creat(),当点击B组件是,相当于A的生命周期的destroy(),再点击回A,相当新创建create了A,所以A是回到默认状态A1,而不是destroy前的状态A2。如果我们想回到A2,则可以使用keep-alive。

router-view也是一个组件(之前分析vue-router源码的时候可见),如果直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存。

所以,大致做法是:将原来的<router-view>标签包含在<keep-alive>标签内。

注意,可能行不通,因为路径关系没有配置好,需要用到activated()激活函数和beforeRouterLeave的组件内守卫。在离开路由组件时,通过beforeRouterLeave函数把路由栈顶路径保存为当前路径,然后activated()每次在激活的页面前把路径压进路由栈,即,保存了每次跳转路由前的路径为栈顶。

前端框架Vue自学之Vue router(六)第62张(home.vue)

所以,整个过程是:点击A,默认打开A1,执行activated(),将A1的路径压进栈,点击A2前一刻,A1要离开了,执行了beforeRouterLeave(),把上一次的路径(A1路径)变为当前路径,因为点击A2,执行activated(),将上一次A1离开时,A1的路径压进栈(即栈顶记录的是上一次点击的组件路径)。当点击B,栈顶的保存的是A2的路径。所以当再点击A时,由于使用了keep-alive,缓存了,所以显示A2。

补充1:activated()和deactivated()这两个函数用于某组件中,在<keep-alive>标签(保持了状态)内的这个组件的<router-view>才有效,没有<keep-alive>包含的话,就不起作用(因为这两个函数是<keep-alive>的钩子函数)。

补充2:keep-alive有两个重要的属性:include,字符串或正则表达式,只有匹配的组件会被缓存;exclude,字符串或正则表达式,任何匹配的组件都不会被缓存。注意多个属性间不用加空格(因为涉及到正则表达规范的问题),如exclude=“Profile,user”不要写成xclude=“Profile, user”。

vue-router的大致知识就是这些了,下一个博客就是关于vue-router的小案例:Tabbar

免责声明:文章转载自《前端框架Vue自学之Vue router(六)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Windows下复制文件命令xcopyC#遇上WINCC下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

进阶攻略|前端最全的框架总结

前端的技术日渐更新,最近得空,花了一上午的时间,将前端常见的UI框架总结了一下,在开发的过程之中,有了这些,不断能够提高自己的工作效率,还可以在工作之余了解更多。希望大家喜欢。 1.Layui 官方网址:http://www.layui.com/ Layui是一款采用自身模块规范编写的国产前端UI框架,遵循原生HTML/CSS/JS的书写与组织形式,门槛极...

Scrapy进阶知识点总结(二)——选择器Selectors

1. Selectors选择器 在抓取网页时,您需要执行的最常见任务是从HTML源提取数据。有几个库可用于实现此目的,例如: BeautifulSoup是Python程序员中非常流行的Web抓取库,它基于HTML代码的结构构造Python对象,并且相当好地处理坏标记,但它有一个缺点:它很慢。 lxml是一个XML解析库(也可以解析HTML),它使用基于E...

Delphi部分函数、命令、属性中文说明

Abort 函数 引起放弃的意外处理Abs 函数 绝对值函数AddExitProc 函数 将一过程添加到运行时库的结束过程表中Addr 函数 返回指定对象的地址AdjustLineBreaks 函数 将给定字符串的行分隔符调整为CR/LF序列Align 属性 使控件位于窗口某部分Alignment 属性 控件标签的文字位置AllocMem 函数 在堆栈上分...

java汉字乱码解决办法

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。一、Java中文问题的由来Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其...

Hibernate-入门教程

首先了解hibernate的目录结构 . +lib antlr.jar cglib-full.jar asm.jar asm-attrs.jars commons-collections.jar commons-logging.jar ehcache.jar hibernate3.jar jta....

uni-app 知识点

---【uni-app】:   是一个使用vue。js开发所有前端应用的框架,开发者编写一套代码,可发布到ios,android,H5,以及各种小程序,   (微信/支付宝/百度/头条/QQ/钉钉)等多个平台 ---【环境搭建】:   1,安装APP开发版HBuilderX   2,安装微信开发者工具 ---【使用HBuilderX初始化项目】:   1,...