Vue-router
Posted PeriHe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue-router相关的知识,希望对你有一定的参考价值。
vue-router
作用:通过管理url,实现url和组件的对应和通过url进行 组件间的切换。
一个url与一个组件是有映射关系的,需要用前端路由来把映射关系一一对应起来。
单页应用
加载单个html页面,并在用户与应用程序交互时动态更新该页面。访问一个网站时,实际上脂肪纹了一个页面。当我们点击导航时并不会跳转页面以及重载页面,而是通过js执行去动态的生成一些结构,把它呈现在我们想要呈现的地方。
单页应用的好处:第一次就会把所有的css,js一次性加载进来。切换链接的时候就不用重新加载资源。
一、使用vue-router步骤:
安装模块:npm install vue-router --save(使用vue-cli就不用这一步)
引入模块:
import Vue from \'vue\' import VueRouter from \'vue-router\'
作为Vue的插件:Vue.use(VueRouter)
创建路由实例对象:
var router = new VueRouter({ 配置参数 })
注入Vue选项参数:
new Vue({ router:router ; //根据ES6 , 可简写为router })
告诉路由渲染的位置:
<router-view></router-view>
举个小栗子:
step1:引入vue-router
import Vue from \'vue\'
import VueRouter from \'vue-router\'
step2:将vue-router作为插件
Vue.use(VueRouter)
step3:引入组件
import App from \'./App\'
import home from \'@/components/home\'
step4:配置路由信息
var router = new VueRouter({ routes:[ { path:\'/\', component:home } ] })
实际应用中,路由配置会很多,所以会把它们放在另外的文件中(router文件夹index.js文件),而不是都写在main.js里面。
step5:注入到根实例
new Vue({ el:\'#app\', router, template:\'<App />\', components:{ App } })
引入文件的时候,可以在webpack.base.config里面配置后缀名,比如说要引入.css文件,就可以找到加上resolve->extensions添加.css:extensions: [\'.js\', \'.vue\', \'.json\', \'.css\']。这样引入css文件就不用谢后缀名了。另外要记住,每次更改了配置文件一定要重启。
下面的内容,将围绕这个小栗子展开:
二、hash和history模式
项目中最常用history模式,但低版本也会使用hash模式。
1.http://localhost:8085/#/ 哈希模式,支持所有浏览器,是默认模式。这里如果a标签不加#号就会刷新页面。
<ul class="nav"> <li> <a href="#/home">home</a> </li> <li> <a href="#/about">about</a> </li> <li> <a href="#/document">document</a> </li> </ul>
2.要想url中不带有#号,就采用history模式,history模式支持前进后退。
路由配置项中添加如下设置为history模式:
mode:\'history\'
另外,a标签会跳转,使用router-view标签来做链接。
三、router-link
功能类似a标签,不会跳转。
<router-link to=\'/home\'>home</router-link>
1.与其他标签一样,可以动态绑定属性(index为data里的数据):
<router-link :to=\'index\'>home</router-link>
2.可以写成对象形式,添加多个配置项...
<router-link :to=\'{path:"/about"}\'>about</router-link>
3.不仅可以作为a标签使用,还可以生成其他标签,如让router-link标签生成的是li标签,给一个tag即可,想要什么写什么:
<router-link :to=\'index\' tag="li">
<i class="fa fa-home"></i>
<span>home</span>
</router-link>
4.激活状态会添加名为router-link-active的class,如图点击第二个li时三个li的class:
名字太长不好记,来取一个好记的代替它,在路由配置里添加一项,将其改成is-active:
linkActiveClass:\'is-active\'
5.将点击切换设置为鼠标移入时切换:
<router-link to=\'/document\' event=\'mouseover\'>document</router-link>
可以通过<router-view>标签来控制整体样式。想要让每个组件都是居中显示,不用再每个组件中设置样式,只要在<router-view>里写就可以了:
<router-view class="center"></router-view>
当在地址栏输入 不匹配的路径 时跳转到404页面。增强用户体验
{ path:\'*\', component:noFound }
也可以用重定向:
四、重定向和别名
1.重定向
{ path:\'*\',
//多种方式重定向: // 1.redirect:\'/home\' // 2.lredirect:{path:\'/home\'} // 3.redirect:{name:\'Home\'} //4.如下: redirect:(to)=>{ //目标路由对象,访问的路径的路由信息 if(to.path === \'/123\'){ return \'/home\' }else if(to.path === \'/abc\'){ return \'/document\' }else{ return \'/about\' } } }
2.别名
在地址栏输入index时,也显示home页面:
{ path: \'/home\', name:\'Home\', component: home, alias:\'/index\' },
3.精确匹配:exact
<router-link exact to="/" tag="li">
五、嵌套路由的使用
在about里面嵌套work,study和study并将study设为默认子路由。在 about 路由配置项的 children 里面写子路由信息:
{ path:\'/about\', component:about, children:[ //子路由 { path:\'\', //默认子路由 name:\'About\', component:study }, { path:\'/work\', name:\'Work\', component:work }, { path:\'/hobbit\', name:\'Hobbit\', component:hobbit } ] }
to可以不写全路径,而是像下面这样,使用name:
<router-link exact :to="{name:\'About\'}" tag="li"><a>study</a></router-link> <router-link :to="{name:\'Work\'}" tag="li"><a>work</a></router-link> <router-link :to="{name:\'Hobby\'}" tag="li"><a>hobby</a></router-link>
六、命名视图
使一个路径对应多个组件的情况。在同级同时展示多个视图,而不是嵌套展示。
在document组件中同时展示slider和document两个视图。
<router-view name="slider"></router-view>
<router-view></router-view>
{
path:\'/document\',
name:\'Document\',
components:{
default:document, // 默认的,渲染到没名字的<router-view>位置
slider:slider //渲染到<router-view name="slider">位置
}
},
七、滚动行为
拉动滚动条,刷新浏览器之后依旧保持在滚动位置,这是浏览器的默认行为。而如果点击前进后退,依旧想要保持在刚刚滚动位置,就要使用到滚动行为。
路由实例配置项中有一个scrollBehavior,点击前进后退或切换导航触发。它有3个参数:
scrollBehavior(to,from,savePosition){ console.log(to); //要进入的目标路由对象 到哪里去 console.log(from); //离开的路由对象 从哪里来 console.log(savePosition); //记录滚动条的坐标 点击前进后退时记录值
if(savePosition){ return savePosition; }else{ return {x:0,y:0}; } },
也可以利用hash定位。
<template> <div> 我是document <p id="abc">定位到这个元素</p> </div> </template>
<router-link to="/document#abc" tag="li">
if(to.hash){ return { selector:to.hash } }
八、动态路径参数
使用场景:匹配到的所有路由,全都映射到同一个组件。比如进入个人信息页面时,每个人进入的页面时一样的,只不过不同用户展示的数据是不一样的。
路径:/user/:userId userId为动态路径参数,不同的用户,userid是不一样的
获取参数:路由信息对象的params
在user里包含n多个用户。当点击不同用户的时候展示不同的信息。
在user组件中遍历写出嵌套结构,userList是准备好的用户数据:
<router-link :to="\'/user/\' + item.id" key="index" v-for="item in userList">{{item.userName}}</router-link>
要想点击用户名就显示相应的用户信息。可以先从路径拿到id,再从id拿到用户信息。
怎么拿到id?
这里就要用到对组件的注入
通过在Vue根实例的router配置传入router实例。
$router 拿到router实例对象
$route 当前激活的路由信息对象
beforeRouteEnter() 进入组件前钩子函数
beforeRouteLeave() 离开组件前钩子函数
created(){ console.log(this.$route) }
在浏览器打印出的route对象:
路由信息对象
一个路由信息对象表示当前激活的路由状态信息,每次成功的导航都会产生一个新对象。
fullPatn:包含hash的完整路径
hash:当前路由的hash值
matched:当前路由嵌套路由
meta:元信息
name:当前路由的名称
params:动态路径参数就是放在这里
path:对应当前路由的路径
query:URL查询参数
所以this.$route.params.userId就可以拿到userId。
然后创建一个空对象userInfo,将来放置拿到的id对应的用户的信息,并遍历显示。
data(){ return{ userList:data, userInfo:{} } },
<p>姓名:{{userInfo.userName}}</p> <p>性别:{{userInfo.sex}}</p> <p>年龄:{{userInfo.age}}</p> <p>爱好:{{userInfo.hobby}}</p>
拿到对应的用户信息,并存在userInfo
created(){ let id = this.$route.params.userId; if(id){ this.userInfo = this.userList.filter((item)=>{ return item.id == id })[0] }else{ userInfo = {} } }
此时就可以显示用户信息了。不过还需要监控路由信息对象,如果路由信息对象发生变化,就要执行created函数。因为在一个组件中操作,组件不会重新生成,所以钩子函数只会执行一次。
watch:{ $route(){ //路径发生变化,就执行这个函数 //就可以找到用户信息啦 this.getData(); } }, created(){ //渲染这个组件会调用一次这个生命周期函数 //复用这个组价这个函数不会再次被调用了 //地址一旦发生变化,$route会生成一个新的路由信息对象 //一旦发生变化,我们就监控到并且执行这个函数 this.getData(); }, methods:{ getData(){ let id = this.$route.params.userId; if(id){ this.userInfo = this.userList.filter((item)=>{ return item.id == id })[0] }else{ userInfo = {} } } }
九、query字符串传参
点击Ta的分享,地址栏变成这个样子--> localhost:8085/user/vip/1?info=share
可以这样:
<div class="info-list" v-if="userInfo.userName" style="font-size:16px;"> <router-link exact to="?info=follow">Ta的关注</router-link> <router-link exact to="?info=share">Ta分享</router-link> </div>
也可以使用query字符串传参
<router-link exact :to="{path:\'\',query:{info:\'follow\',a:1}}">Ta的关注</router-link> <router-link exact :to="{path:\'\',query:{info:\'share\',a:1}}">Ta分享</router-link>
点击之后路径就会变成这样:http://localhost:8085/user/vip/1?info=follow&a=1
<router-link style="padding: 0 20px" :to="{path:\'/user/\'+ item.tip+\'/\'+item.id,query:{info:\'follow\'}}" key="index" v-for="item in userList">{{item.userName}}</router-link>
默认激活follow。
十、编程式导航
之前借助于router-link实现导航的切换,也可以借助于router的实例方法,通过编写代码来实现导航的切换,
back 回退一步
forward 前进一步
go 指定前进后退步数
push 导航到不同url,向history栈添加一个新纪录
replace 导航到不同url,替换history栈中当前记录
十一、导航钩子函数
导航发生变化时,导航钩子主要用来拦截导航,让它完成跳转或取消
执行钩子函数的位置
router全局
单个路由
组件中
钩子函数
router实例上:beforeEach,afterEach
单个路由上:beforeEnter
组件内的钩子:beforeRouterEnter,beforeRouterUpdate,beforeRouterLeave
钩子函数接收的参数
to 要进入的目标路由对象
from 正要离开导航的路由对象
next 用来决定是否进入导航或者跳转
以上是关于Vue-router的主要内容,如果未能解决你的问题,请参考以下文章