Vue路由 - vueRouter
起步:
-
什么是路由?
根据用户请求的路径来展示不同的页面或者返回不同的数据,又分为前端路由和后端路由。 前端路由: 根据用户请求不用的Url 来展示不同的页面或者数据,前端路由是不会涉及到后端请求的,以及页面 不会进行刷新的,用户体验比较好,一般用来做单页面的开发,前端路由的底层原理:hashchange 和 popState 和replaceSstate。 后端路由: 根据用户请求的路径来返回不同的数据或者页面,后端路由一般情况下是用来做接口的,通过ajax 请求的路径返回相对应的数据
开始:
- 安装:
cnpm/npm install vue-router
yarn add vue-router
- 配置: 建议将router单独写成一个文件,在文件中进行配置,代码示例如下。
import Vue from "vue"; //引入Vue
import VueRouter from "vue-router"; //引入vue-router 插件
Vue.use(VueRouter); // 使用插件
import IndexTpl from "../views/index.vue" //引入相关的模板
import MovieTpl from "../views/movie.vue" //引入相关的模板
import MineTpl from "../views/mine.vue" //引入相关的模板
let routeMaps =[ // 进行路由表的配置,是一个数组,每一个对象对应一个相应的路径以及模板。
{
path:"/index",
component:IndexTpl
},
{
path:"/movie",
component:MovieTpl
},
{
path:"/mine",
component:MineTpl
},
]
let router = new VueRouter({
routes:routeMaps //将路由表的配置载入vue-router实例
})
export default router //模块化进行导出
- 使用及相关说明:
相关说明: 在 vue-router的实例挂载到 Vue实例身上的时候,**Vue **就会多出两个内置组件,一个是 router-link ,一个是 router-view。- router-link详解: 用来进行路由的跳转,里面有两个自带属性,一个是 tag ,值为想要渲染为什么元素,另一个是 to,值为要跳转的地址,如果跳转的地址是动态的要在 to 前加 :。它的底层原理是用a标签的href属性来实现跳转的。
- router-view详解 :用来展示跳转的地址对应的组件,标签写在哪里,对应地址的组件就被放在哪里。底层原理的实现,用了插槽,用来显示首页、电影等数据。
- active-class详解: 添加了此属性的 router-link ,被选中时,就会给当前元素绑定对应值的样式。
简单的实现:
点击切换
4. 路由表的详细配置: routes 配置
属性 | 作用 | 示例 |
---|---|---|
path | 匹配路由的路径 | /index |
component | 路由路径匹配成功以后会显示相对应的组件 | IndexTemplate |
redirect | 路由重定向 | /mine |
name | 路由名称 | index |
props | 路由解耦 | true |
children | 路由嵌套/多级路由 | /user/login |
meta | 路由元信息,当前路由独有的数据 | meta:{ a: 2 } |
二级路由:
5. Vue路由跳转方式:
Vue 路由跳转方式共有三种,一种直接用 a 标签,利用 href 属性进行地址跳转,第二种利用自带组件 router-link 中的 to 属性进行地址的跳转,它的底层原理也是利用 a 标签中的 href 属性,第三中是编程式导航( 就是使用原生JS的方式 )进行跳转。
router-link:
a 标签:
编程式导航:
编程式导航跳转包括:
- this.$router.push //跳转到某一个地址
- this.$router.go //前进几个历史记录
- this.$router.back //后退几个历史记录
- this.$router.forword //前进
- this.$router.replace //替代某一地址
6 . 路由传值: 各个路由对应的页面间的数据传递。
路由传值方式有三种:动态路由传值 、query传值 、编程式导航传值 。
- 动态路由传值:
接收:在定义路的时候,在需要接收值的 path 路径处通过 ( / :key )的方式来定义传递参数的属性名。
传递:在路由跳转的时候,在路径跳转的地方通过 / value 的方式来进行传递。接收的时候定义几个属性,传递的时候就必须写几个属性。
在接受的组件页面通过this.$route.prams
进行页面渲染。
传值结果: - query 传值: 所谓的 query 传值,就是通过 url 地址拼接进行数据传递。在path处不需要配置。
传递的时候:在路由跳转的时候,通过 路径
/ ?key1 = value1 & key2 = value2
进行数据传递。
在组件中通过this.$route.query
进行渲染。
传值结果: - 编程式导航传值: 在编程式导航跳转地址的时候,将参数拼接到地址后面。可以 params 方式也可以 query 方式,接收时,使用对用的接收方式即可。
一些优化:以上三种方式通用
- 当路由处 path 配置了路由名称属性(name ) ,传递时,可以采用对象的方式进行传递,就不再用进行字符串的拼接了。
接收时可通过this.$route.params
进行接收。
后面的params也可以换成query,这取决于你用什么接收。 - 当路由处配置了路由解耦属性(props:true ) ,而且传值方式为动态路由传值时,接收的时候可以使用 props 的属性来接收,与data属性平级。
props:["username","possword"]
Vue路由生命周期——也叫路由钩子函数或者路由守卫:
- 全局路由守卫 :beforeEach , 有三个参数 , to :到哪个路由去 。 from :从哪个路由来 。 next :加载路由对应的组件,如果不执行 next 就不会渲染组件。在 to 和 from 中 可以访问到路由的元信息。
全局的路由守卫是在路由配置中使用的。
router.beforeEach((to, from, next) => {
document.title = to.meta.title // 将网站的title,动态改变。
if(!to.meta.mustlogin){
// 如果访问的页面必须登录之后才行
next()
}else {
next({name:"login"}) // 如果必须登录之后才可以访问的页面,就跳转到登录页面
}
})
-
局部路由守卫 :beforeRouterEnter - 路由进入时、beforeRouterUpdate - 路由更新时、beforeRouterLeave - 路由离开时。 也有以上三个参数。用法也一样。
局部路由守卫是在组件中写的,这个守卫为这个组件独有。
-
使用场景:
beforeRouterEnter 主要用在 : 验证是否登录、验证Vip时间是否到期、以及用户的一些权限等等。
beforeRouterLeave 主要用在 :用户未支付、答题系统的存档、记录历史记录、注销或者切换账号的确定、
Vue路由实现的底层原理:
let Vue; //当 Vue使用插件的时候,会传递一个Vue对象,用来储存此对象
class VueRouter{
//接收Vue.use传递过来的Vue
static install(_Vue){
Vue = _Vue; // Vue.use 的 组件中 必须有一个 install 的 方法。
}
constructor(options){
//接收传递过来的配置项
this.$options = options;
//定义解析routes对象的变量
this.routeMap = {};
//定义路由的地址
this.app = new Vue({
data:{
curr:"/"
}
})
//调用初始化方法
this.init();
}
init(){
//1、绑定路由事件
this.bindEvent();
//2、创建路由对象
this.createRouteMap()
//3、创建组件
this.createComponents();
}
bindEvent(){
window.addEventListener("load",this.handleChange.bind(this));
window.addEventListener("hashchange",this.handleChange.bind(this))
}
handleChange(){
//更新视图
var hash = this.getHash() || "/";
this.app.curr = hash;
}
getHash(){
return location.hash.slice(1);
}
createRouteMap(){
this.$options.routes.forEach((item)=>{
this.routeMap[item.path] = item; // 解析传过来的路由表配置
})
}
createComponents(){ // 创建两个自带的组件
Vue.component("router-view",{
render:h=>{
var component = this.routeMap[this.app.curr].component;
return h(component)
}
})
Vue.component("router-link",{
props:{
to:{
type:String, // 绑定一个自定义属性,父子传值方法。
required:true
}
},
render:function(h){ // 体现了 router-link 的 底层原理是 利用了 a 标签的 href 属性
return h("a",{
attrs:{
href:`#${this.to}`
}
},
this.$slots.default //用插槽来取到相应的数据。比如首页、我的
)
}
})
}
}
export default VueRouter;