路由
路由的概念
路由的本质就是一种对应关系
(此处的路由含义同之前nodejs的路由),根据不同的URL请求,返回对应不同的资源。那么url地址和真实的资源之间就有一种对应的关系,就是路由。
路由分为:后端路由
和前端路由
- 后端路由:由服务器端进行实现并实现资源映射分发(nodejs、jsp、php等)
- 概念:根据不同的用户URL请求,返回不同的内容(地址与资源产生对应关系)
- 本质:URL请求地址与服务器资源之间的对应关系(映射)
- 前端路由:根据不同的事件来显示不同的页面内容,是事件与事件处理函数之间的对应关系
- 概念:根据不同的用户事件,显示不同的页面内容(地址与事件产生对应关系)
- 本质:用户事件与事件处理函数之间的对应关系
记住一句话:有请求就应该有响应,只不过区别在于,之前node是响应资源,现在在前端中通过事件来进行响应。
前端路由实现
面试题:请你说出前端路由是怎么实现的?或者有哪几种实现方式?
答:前端路由模式有两种实现方式:hash方式、history方式。
核心思想:通过监听地址栏的变化事件来实现资源的动态显示
前端路由有2种模式:
- hash模式
hash路由模式是这样的:http://xxx.abc.com/#/xx。 有带#号,后面就是hash值的变化。改变后面的hash值,它不会向服务器发出请求,因此也就不会刷新页面。并且每次hash值发生改变的时候,会触发hashchange事件。因此我们可以通过监听该事件,来知道hash值发生了哪些变化。
window.addEventListener('hashchange', ()=>{ // 通过 location.hash 获取到最新的 hash 值 console.log(location.hash); });
- history模式
形如:http://xxx.abc.com/xx/yy/zz。HTML5的History API为浏览器的全局history对象增加了该扩展方法。它是一个浏览器(bom)的一个接口,在window对象中提供了onpopstate事件来监听历史栈的改变,只要历史栈有信息发生改变的话,就会触发该事件。
history.pushState({},title,url); // 向历史记录中追加一条记录 history.replaceState({},title,url); // 替换当前页在历史记录中的信息。 window.addEventListener('popstate', function(event) { console.log(event) })
注:浏览器地址没有#, 比如(http://localhost:3001/a); 它也一样不会刷新页面的。但是url地址会改变。但它在服务器没有配置的情况下,不能手动刷新,否则返回404页面
Vue Router
网址:https://router.vuejs.org/zh/,vuerouter是vue全家桶(vue+vue router+vuex )之一。
vue周边生态软件、工具
此处建议创建一个带Router的vue项目。
介绍
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由(套娃,父子路由)
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 带有自动激活(默认选中效果)的 CSS class 的链接
- HTML5 历史模式或 hash 模式
MVVM框架采用的路由都会在地址改变的时候页面不刷新,这种应用我们称之为SPA(Single Page Application)
路由模式切换
vue-router中默认使用的是hash模式的路由,也就是前面介绍的地址栏中URL带有“#”的形式,如果需要切换成history模式,则可以在创建路由实例时进行指定,指定的配置项为mode
,可选值:
- hash:设置路由模式为hash路由
- history:设置路由模式为history路由
导航方式
含义:从一个组件/地址去往另一个组件/地址的方式。
在页面中,导航实现有2种方式:
- 声明式导航:通过点击链接实现的导航方式,例如HTML中的“”标签,Vue中的“”所实现的。(其性质与a标签的性质类似)
- 编程式导航:通过调用JavaScript形式API实现的导航方式,例如location.href实现的跳转效果
声明式导航
它就是先在页面中定义好跳转的路由规则,vueRouter中通过router-link组件来完成
<!-- 纯字符串 --> <router-link to="/home">Home</router-link> <!-- 动态绑定路径 --> <router-link :to="'/home'">Home</router-link> <!-- 对象形式 --> <router-link :to="{ path: '/home' }">Home</router-link> <!-- 通过路由命名并且携带隐式参数 --> <router-link :to="{ name: 'user', params: { userId: '123' }}">User</router-link> <!-- 对象形式带查询字符串 --> <router-link :to="{ path: '/register', query: { plan: 'private' }}"> Register </router-link> <!-- to 要跳转到的路由规则 string|object to="users" :to="{path:'path'}" tag="tagName" 去指定声明式导航产生的链接所使用的标签,默认是a标签 -->
编程式导航
简单来说,编程式导航就是通过JavaScript
来实现路由跳转
this.$router.push("/login"); this.$router.push({ path:"/login" }); this.$router.push({ path:"/login",query:{username:"jack"} }); // 不要将path属性与params属性一起使用,这样会导致params路由参数获取不到 // name属性可以与params属性传参一起使用 this.$router.push({ name:'user' , params: {id:123} }); this.$router.go( n );//n为数字 负数为回退 this.$router.back(); // 返回上一页
**注意点:**编程式导航在跳转到与当前地址一致的URL时会报错,但这个报错不影响功能:
如果患有强迫症,可以在路由入口文件index.js
中添加如下代码解决该问题:
// 该段代码不需要记,理解即可 const originalPush = VueRouter.prototype.push; VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch((err) => err); };
面试题问题:this.$router
与this.$route
有什么区别?
答:$router
是用于做编程式导航的(改变路由的);$route
是用户获取路由信息的。