路由相关

248 阅读3分钟

1. 谈谈前端路由

前端路由原理

前端路由实现起来其实很简单,本质就是监听URL的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。即更新视图但不重新请求页面

前置知识

history 对象
保存用户上网的历史记录

History.png

history.pushState()history.replaceState()

  • 第一个参数data是给state的值-也是popState中的event.state的值;
  • 第二个参数title为页面的标题,但当前所有浏览器都忽略这个参数,传个空字符串就好;
  • 第三个参数url是你想要去的链接;

注意:

当活动历史记录条目更改时,将触发popstate事件。
需要注意的是调用history.pushState()history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者history.forward()方法)

location 对象

前端路由两种实现方式

  • Hash模式
  • History模式

Hash模式

利用hash值改变,页面不会重现加载。 举例:

www.test.com/#/ 就是hash模式,当#后面的哈希值发生变化时,可以通过hashchange事件监听url的变化,从而跳转页面。 而且无论哈希值如何变化,服务器端接收的url请求永远都是 www.test.com/#/

实现:

window.addEventListener('hashchange',(event)=>{
    ... // 监听hash变化,点击浏览器的前进后退会触发。
})

优点:

hash模式相对而言更简单,并且兼容性更好。


History模式

举例:

History 模式是 HTML5 新推出的功能,主要使用 history.pushStatehistory.replaceState 改变 URL。这2个方法,改变 URL 不会引起页面的刷新,只会更新浏览器的历史记录。

// 新增历史记录
history.pushState(stateObject,title,URL);
// 替换当前记录
history.repalceState(stateObject,title,URL);

当用户做出浏览器动作时,比如点击后退按钮时会触发 popState 事件

window.addEventListener('popState',(e)=>{
    // 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发      
    // e.state 是pushState(stateObject,title,URL)中的stateObject;
})

优点:

两种模式对比

  • Hash 模式只可以更改 # 后面的内;History 模式可以通过 API 设置任意的同源 URL。
  • Hash 模式只能更改哈希值,也就是字符串;History 模式可以通过 API 添加任意类型的数据到历史记录中。
  • Hash 模式无需后端配置,并且兼容性好;History 模式在用户手动输入地址或者刷新页面的时候会发起 URL 请求,后端需要配置 index.html 页面用于匹配不到静态资源的时候。

Vue Router

router.push 本质是模仿 window.history.pushState
router.replace本质是模仿window.history.replaceState
router.go 本质是模仿window.history.go 
vue router导航实际上是效仿 window.history API 的。

Vue Router 的导航方法 (push、 replace、 go) 在各类路由模式 (history、 hash 和 abstract) 下表现一致。

2. route VS router

$router : 是路由操作对象,只写对象

$route : 路由信息对象,只读对象

3. 路由跳转方式name、path 和传参方式params、query的区别

一般原则:

name + params搭配使用: 需设置动态路由

path + query搭配使用

因为:
path + params 路由跳转方式,params传参会被忽略,可改为name + params方式。
技巧:name + query 方式没啥问题。

注意
name + params传参如果没有设置动态路由,
也是可以传过去的,但不会在url上面显示出你的参数,并且当你跳到别的页面或者刷新页面的时候参数会丢失。
要怎么解决?

解决方式2种:

  • 传参字符串name小的时候,设置动态路由-在路由后面加参数名/router1/:name

也就是当你通过params传参时,需要设置动态路由。

  • name大的时候用localStorage;