1. 谈谈前端路由
前端路由原理
前端路由实现起来其实很简单,本质就是监听URL的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。即更新视图但不重新请求页面
前置知识
history 对象
保存用户上网的历史记录
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.pushState
和 history.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;