路由是路径和组件的映射关系
为什么要使用路由?
ue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。
vue-router实现原理
SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;
路由模式有哪些?
1、Hash模式:
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。 hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据
2、History模式:
由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: 'history'",这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
hash模式:
- 浏览器中符号是“#”,#以及#后面的字符称之为 hash,又叫前端路由
- 用 window.location.hash 读取
- hash 虽然在 URL 中,但不被包括在 HTTP 请求中
- hash 改变会触发 hashchange 事件
- hash发生变化的url都会被浏览器记录下来,从而浏览器的前进后退都可以用
history模式:
- history 采用 HTML5 的新特性
- history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中
- 它也有个问题:不怕前进,不怕后退,就怕刷新(如果后端没有准备的话,会分分钟刷出一个404来。Html5history在打包上线后需要后端支持配置),因为刷新是实实在在地去请求服务器的。 在生成路由对象出修改模式,mode: "history"
vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质 就是建立起url和页面之间的映射关系。
项目中的配置路由
引入vue -----配置路由文件
import Vue from "vue";
1.引入路由
import VueRouter from "vue-router";
2.注册组件
Vue.use(VueRouter)
3.定义路由规则
const routes = [
{
path:'/', //默认路由
redirect:"/login" //重定向
},
{
path:'/login',
component:()=>import("@/views/login.vue")
}
]
4.根据路由规则生成路由对象
const router = new VueRouter({
routes
})
5.导出路由
export default router
6.在main.js 引入路由,把路由注入到的new vue实例中 router
7.在 APP.vue设置挂载点 <router-view/>
配置路由根据业务需要来设置,基本的路由配置有:
重定向
- 网页打开url默认hash值是/路径
- (相当于替换) redirect是设置要重定向到哪个路由路径
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配数组规则
}
]
总结: 强制重定向后, 还会重新来数组里匹配一次规则
路由定义
引入路由文件
{
path: "/part",
component: Part
},
或者也可以这样写:
{
path:'/part',
component:()=>import("@/views/part.vue")
}
404页面
如果路由hash值, 没有和数组里规则匹配,默认给一个404页面
const routes = [
// ...省略了其他配置
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
路由传参方式
先介绍两种导航,声明式导航和编程式导航两种。
声明式导航 - 基础使用
vue-router提供了一个全局组件router-link(另一个是router-view)router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)router-link提供了声明式导航高亮的功能(自带类名)
声明式导航--自带高亮类名
- router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
- router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径
编程式导航 - 基础使用
语法:
path: "路由路径", // 都去 router/index.js定义
name: "路由名"
})
例如:// this.$router.push('/my')
// this.$router.push('/part/123')
1.编程式导航用JS代码跳转。特殊情况下才能使用,有一定的条件。如:判断用户已登录才跳转
2.声明式导航组件标签的形式跳转,相当于利用a标签的href属性
3、
this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面
4、
this.$router.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数。 后退:this.$router.back() 前进 :this.$router.forward()
传参方式
声明式导航传参
- to="/path?参数名=值" ---------- $route.query.参数名
- to="/path/值 "– 路由配置 path: “/path/:参数名” -----------$route.params.参数名
编程式导航传参
进阶使用:传对象的形式,适用于参数较多的复杂情况,语法:
path: "路由路径",
query: {
"参数名": 值
}
或
this.$router.push({
path: "路由路径",
name: "路由名", //最好带上name
params: {
"参数名": 值
}
//路由配置要写
{
path: "/part/:id",
name:'part',
component:Part
// component: ()=>import("@/views/Part.vue")
},
* 例如:*
//querry方法
this.$router.push({
path: '/part',
query: { id: 123, a: 'abc' },
}),
//params方法
this.$router.push({
name: 'part',
params: {
id: 789,
},
})
})
// 对应路由接收 $route.params.参数名 取值
// 对应路由接收 $route.query.参数名 取值
嵌套路由(二级路由)
就是在现有一级路由下再嵌套二级路由、三级路由...嵌套路由要 找准在哪个页面里写router-view(页面挂载)、router-link(页面展示)和对应规则里写children,配置路由的规则同上。
例如:
const routes = [
// ...省略其他
{
path: "/find", //一级路由
name: "Find",
component: Find,
children: [
{
path: "recommend",
component: Recommend //二级路由
},
]
}
]
全局导航守卫
在路由跳转之前, 先执行一次前置守卫函数, 判断路由权限是否可以正常跳转。
使用场景:通常在登录页面对token值进行判断,来确认是否登录
语法: router.beforeEach((to, from, next)=>{
//路由跳转"之前"先执行这里, 决定是否跳转
})
参数1: 要跳转到的路由 (路由对象信息) 目标
参数2: 从哪里跳转的路由 (路由对象信息) 来源
参数3: 函数体 - next()才会让路由正常的跳转切换, next(false) 在原地停留, next("强制修改到另一个路由路径上")
例子:
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})