博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue中对router路由的总结理解
阅读量:3902 次
发布时间:2019-05-23

本文共 10802 字,大约阅读时间需要 36 分钟。

一个完整的URL由几部分组成?

https://www.icketang.com/static/img/banner_news.jpg?num=10&color=red#title

协议 https://

域名 www.baidu.com

端口号 :443

路径 /static/img/

搜索词 ?num=10&color=red

哈希 #title

前三个部分的改变会导致跨域的问题。

前五个部分的改变会导致浏览器端向服务器端发送新的请求。

hash模式

只有hash的改变不会导致浏览器端向服务器端发送新的请求

浏览器不发出请求,也就不会刷新页面。每次 hash 值的变化,会触发hashchange 这个事件,通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听hashchange来实现更新页面部分内容的操作

// 监听路由变化window.addEventListener('hashchange', router)// 路由方法function router() {	// console.log(location.hash)	// 截取组件的名称	let page = location.hash.slice(2);	// 更新页面	app.page = page;}// 页面加载完成执行router();

history模式

因为HTML5标准发布,多了两个 API,pushState()replaceState()。通过这两个 API (1)可以改变 url 地址且不会发送请求,(2)不仅可以读取历史记录栈,还可以对浏览器历史记录栈进行修改。

除此之外,还有popState().当浏览器跳转到新的状态时,将触发popState事件.

修改历史状态

包括了pushState,replaceState两个方法,这两个方法接收三个参数:stateObj,title,url

window.history.pushState(stateObject, title, URL)window.history.replaceState(stateObject, title, URL)

切换历史状态

包括back,forward,go三个方法,对应浏览器的前进forward,后退back,跳转go操作。   有同学说了,(谷歌)浏览器只有前进和后退,没有跳转,嗯,在前进后退上长按鼠标,会出来所有当前窗口的历史记录,从而可以跳转(也许叫跳更合适):

  1. history.go(-2);//后退两次

  2. history.go(2);//前进两次

  3. history.back(); //后退

  4. hsitory.forward(); //前进

区别:

  • 前面的hashchange,你只能改变#后面的url片段。而pushState设置的新URL可以是与当前URL同源的任意URL。
  • history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误

当用户刷新页面之类的操作时,浏览器会给服务器发送请求,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面

 

history模式怕啥

不怕前进,不怕后退,就怕刷新,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的。

在history模式下,你可以自由的修改path。history模式最终的路由都体现在url的pathname中,这部分是会传到服务器端的,因此需要服务端对每一个可能的path值都作相应的映射。

当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。

那么在vue中如何使用路由?

使用路由共分六步:

第一步 在模块化开发中,通过use方法安装路由

第二步 定义路由渲染位置。

通过router-view组件

第三步 定义页面组件。

路由简化了组件的定义

只需要定义extend参数对象集合

第四步 定义路由规则:

路由规则是一个数组,每一个成员代表一条规则,是一个对象:

path 定义规则,类似express中的路由规则

用/切割路径,默认是静态路由

静态路由:是一个一对一的路由规则

例如 /home/ickt 只对应  /home/ickt

在名称的前面,添加:就是一个动态路由规则了

动态路由:是一个一对多的路由规则,

例如 /list/:page

匹配 /list/10 /list/100 /list/abc

不匹配 /list /list/10/20 /detail/10

component 渲染的组件对象

name 组件名称

...

第五步 实例化路由,并传递路由规则:routes

第六步 在vue实例化对象中,注册路由,通过router属性。

默认路由

当没有匹配到路径,希望渲染默认页面的时候,可以使用默认路由。

直接将path匹配*即可。

      路由重定向

当我们输入一个地址,想渲染另外一个页面。此时可以使用路由重定向技术。

通过path匹配地址

通过redirect属性配置重定向的地址。

header

// 引入vueimport Vue from 'vue';// 引入路由import Router from 'vue-router';// 1 安装路由Vue.use(Router);// 3 定义组件let Home = { template: '

home page

' }let List = { template: '

list page

' }let Detail = { template: '

detail page

' }// 4 定义规则let routes = [ // 每一个成员代表一条规则 { path: '/home', component: Home, name: 'home' }, // 列表页 { path: '/list/:page', component: List, name: 'list' }, // 详情页 { path: '/detail/:id', component: Detail, name: 'detail' }, // 路由重定向 { path: '/ickt', redirect: '/detail/ickt' }, // 默认路由 { path: '*', component: Home }];// 5 实例化路由 将规则传递进来let router = new Router({ routes })// 实例化let app = new Vue({ // 6 注册路由 router, // 视图 el: '#app', // 数据 data: {}})

路由参数

我们在vue实例化对象中,注册了router,此时所有的组件都会继承两个属性:$router, $route

添加给组件实例化对象自身,并设置了特性,所以即可在模板中使用,也可以在组件中使用。

$router 代表路由实例化对象,管理路由,提供了一些操作路由的方法:

 $route 存路由信息

fullPath 完整路径

hash 路由上的的hash(hash路由中url上第二个#后面的)

path 路径

query search数据(被解析成了对象)

params 动态路由数据(被解析成了对象)

路由传递参数 props

我们在定义路由规则的时候,

可以设置props属性,可以为渲染的组件,传递属性数据

此时组件要通过props属性接收数据

props: true 将动态路由数据直接传递给组件,

props: fn

函数参数是route对象

返回值对象中的属性会传递给组件。

let routes = [	// 每一个成员代表一条规则	{ path: '/home', component: Home},	// 列表页	{ 		path: '/list/:page', 		component: List, 				// 函数传递多个属性		props(route) {			// console.log(arguments)			return {			id: route.params.itemId,                        articleTitle: route.query.draft			}		}	}	];

跳转到ist页面时:

this.$router.push({       path: "/article/" + id,       query: {            articleTitle: "文章1"       }})

 在list页面组件上接收参数:

props: {   id: String,   articleTitle: String}

子路由

在页面的某个区域切换子页面,我们可以使用子路由。

使用子路由分成两步

第一步 定义子路由的渲染位置

在父路由模板中,通过router-view来定义

第二步 在路由规则中,我们通过children属性定义子路由配置

是一个数组,每一个成员代表是一个子路由配置对象,

可以配置:path, component, name, redirect, props, children ...

path可以是绝对路径,也可以是相对路径

如果是绝对路径:以/开头的

完整路径:子路由路径

如果是相对路径:不是以/开头的

完整路径:父路由路径+子路由路径

header

// 引入vueimport Vue from 'vue';// 引入路由import Router from 'vue-router';// 1 安装路由Vue.use(Router);// 3 定义组件let Home = { template: '

home page

' }let List = { template: '

list page

' }let Detail = { template: '

detail page

' }//子路由页面let Nav = { template: '

nav page

' }// 4 定义规则let routes = [ // 每一个成员代表一条规则 { path: '/home', component: Home, name: 'home' }, // 列表页 { path: '/list/:page', component: List, name: 'list' }, // 详情页 { path: '/detail/:id', component: Detail, name: 'detail' //定义子路由 children:[ //绝对路径 {path:"/demo",componet:Nav} //相对路径 {path:"/demo/:nav", componet:nav} ] }, ];// 5 实例化路由 将规则传递进来let router = new Router({ routes })// 实例化let app = new Vue({ // 6 注册路由 router, // 视图 el: '#app', // 数据 data: {}})

路由模式

我们通过mode属性定义路由模块

默认是hash路由,

我们可以设置成history路由(基于path切换页面的)

这种模式需要服务器端的配置

我们在实例化路由的时候,配置路由模式

滚动条

我们在切换页面的时候,可以设置滚动条位置

通过scrollbehavior方法设置滚动条位置

第一个参数表示当前路数据由对象

第二个按时表示上一个路由数据对象

第三个参数表示当前滚动条位置

返回值就是设置的滚动条位置

x 代表水平方向滚动条位置

y 代表垂直方向滚动条位置

// 5 实例化路由let router = new Router({ 	routes,	// 路由模式	// mode: 'history',	// 设置滚动条位置   获取跳转跳转新页面时的位置	// scrollBehavior() {	// 	// console.log(arguments)	// 	return {	// 		x: 0,	// 		y: 200	// 	}	// }})

路由导航

路由导航是用来切换路由的。

html中切换页面通过a标签的href属性

js中切换页面通过location对象

为了简化页面的切换,vue提供了路由导航组件:router-link。

to 必须的,用来设置地址,

即使是hash路由,不要加#

tag 用来设置渲染的元素

默认渲染成a标签

v-text 设置内容

是指令,属性值是js环境

内容还可以直接写在组件内

home
list
// 引入vueimport Vue from 'vue';// 引入路由import Router from 'vue-router';// 引入样式import './demo.scss';// 1 安装路由Vue.use(Router);// 4 定义规则let routes = [ // 每一个成员代表一条规则 { path: '/home', component: Home, name: 'home' }, // 列表页 { path: '/list/:page', component: List, name: 'list', }, // 详情页 { path: '/detail/:id', component: Detail, name: 'detail', }, ];// 5 实例化路由let router = new Router({ routes,})// 实例化let app = new Vue({ // 6 注册路由 router, // 视图 el: '#app', // 数据 data: {}})

路由过渡

路由过渡允许我们在切换页面的时候,添加过渡动画,

使用方式跟以前使用过渡的方式是一样的。

通过transition组件使用,通过name属性定义过渡名称。

我们可以使用mode属性设置过渡模式

例如:out-in模式

         
// 引入vueimport Vue from 'vue';// 引入路由import Router from 'vue-router';// 引入样式import './demo.scss';// 1 安装路由Vue.use(Router);// 3 定义组件let Home = { template: '

home page

' }let List = { template: '

list page

' }let Detail = { template: '

detail page

' }// 4 定义规则let routes = [ // 每一个成员代表一条规则 { path: '/home', component: Home, name: 'home' }, // 列表页 { path: '/list/:page', component: List, name: 'list', }, // 详情页 { path: '/detail/:id', component: Detail, name: 'detail', }, ];// 5 实例化路由let router = new Router({ routes,})// 实例化let app = new Vue({ // 6 注册路由 router, // 视图 el: '#app', // 数据 data: {}})

路由守卫

为了保证watch长期有效,我们可以使用keep-alive组件。

// 引入vueimport Vue from 'vue';// 引入路由import Router from 'vue-router';// 1 安装路由Vue.use(Router);// 3 定义组件let Home = { template: '

home page

' }let List = { // 接收属性数据 props: [ 'page', 'color', 'num' ], template: `

list page

`, // 局部路由守卫 to: Route:即将要进入的目标 路由对象 from: Route: 当前导航正要离开的路由 // beforeRouteEnter(route, oldRoute, next) { // console.log(arguments); // // next方法必须执行 // next(); // }, // watch监听器监听路由变化 watch: { $route() { console.log(arguments) } }, // 组件创建完成 created() { console.log(this, this.$route) }}let Detail = { template: `

detail page

}// 4 定义规则let routes = [ // 每一个成员代表一条规则 { path: '/home', component: Home, name: 'home' }, // 列表页 { path: '/list/:page', component: List, name: 'list', }, // 详情页 { path: '/detail/:id', component: Detail, name: 'detail', } ];// 5 实例化路由let router = new Router({ routes, })// 全局路由守卫// router.afterEach((...arg) => console.log(arg))// router.beforeEach((route, oldRoute, next) => {// console.log(route, oldRoute, next)// // next方法必须执行,否则看不到新的页面// next();// })// 实例化let app = new Vue({ // 6 注册路由 router, // 视图 el: '#app', // 数据 data: {}})console.log(Vue.version)

vue-router有哪几种导航钩子( 导航守卫 )?

1、全局守卫: router.beforeEach

2、全局解析守卫: router.beforeResolve

3、全局后置钩子: router.afterEach

4、路由独享的守卫: beforeEnter

5、组件内的守卫: beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave

导航表示路由正在发生改变,vue-router 提供的导航守卫主要用来:通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

注意:参数或查询的改变并不会触发进入/离开的导航守卫。 你可以通过 观察 $route 对象 来应对这些变化,或使用 beforeRouteUpdate的组件内守卫。


1、全局守卫:

使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })  router.beforeEach((to, from, next) => {  // ...})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中

每个守卫方法接收三个参数:

to: Route:即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function:一定要调用该方法来resolve这个钩子。执行效果依赖 next 方法的调用参数。

  • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed (确认的)。

  • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

  • next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在router-link的 to prop或 router.push中的选项。

  • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError()注册过的回调。

确保要调用 next方法,否则钩子就不会被 resolved

2、全局解析守卫:

2.5.0 新增

在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是:在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

3、全局后置钩子
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => {  // ...})

4、路由独享的守卫

你可以在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({  routes: [    {      path: '/foo',      component: Foo,      beforeEnter: (to, from, next) => {        // ...      }    }  ]})

这些守卫与全局前置守卫的方法参数是一样的。

5、组件内的守卫

最后,你可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter

beforeRouteUpdate (2.2 新增)

beforeRouteLeave

const Foo = {  template: `...`,  beforeRouteEnter (to, from, next) {    // 在渲染该组件的对应路由被 confirm 前调用    // 不!能!获取组件实例 `this`    // 因为当守卫执行前,组件实例还没被创建  },  //不过,你可以通过传一个回调给 next来访问组件实例。  //在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。  beforeRouteEnter (to, from, next) {    next(vm => {      // 通过 `vm` 访问组件实例    })  },  beforeRouteUpdate (to, from, next) {    // 在当前路由改变,但是该组件被复用时调用    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。    // 可以访问组件实例 `this`  },  beforeRouteLeave (to, from, next) {    // 导航离开该组件的对应路由时调用    // 可以访问组件实例 `this`  }}

注意:beforeRouteEnter 是支持给next 传递回调的唯一守卫。对于beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了:

beforeRouteUpdate (to, from, next) {  // just use `this`  this.name = to.params.name  next()}

离开守卫beforeRouteLeave:通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消:

beforeRouteLeave (to, from , next) {  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')  if (answer) {    next()  } else {    next(false)  }}

转载地址:http://klven.baihongyu.com/

你可能感兴趣的文章
PMO根据项目类别管理和控制偏差
查看>>
写给项目经理一封管理改善邮件
查看>>
结项审计管理规范指南
查看>>
QA与PMO联合工作程序
查看>>
小微软件公司敏捷管理实施主题研讨纪要
查看>>
项目干系人管理
查看>>
《禅道》建“任务”注意事项
查看>>
配置管理培训概览
查看>>
CMMI4 培训计划
查看>>
度量与分析培训
查看>>
实施质量管理的实践
查看>>
用户需求开发优先级排序
查看>>
20个成功的项目管理经验
查看>>
研发配置管理流程
查看>>
用户访谈的提纲
查看>>
软件产品发布基本流程
查看>>
产品集成检查列表
查看>>
CMMI认证准备工作任务
查看>>
IT服务工具分类
查看>>
某企业需求工程师培训情况调研
查看>>