服务端渲染的多页应用(SSR)
在还没有前后端分离的时候,通常是后端负责服务端程序,配合JQuery,来实现整个应用。
- 缺点:维护特别麻烦、服务器压力大(整个项目都会部署在自己的服务器上)、没有前后端分离,协作流程不清晰
- 优点:SEO效果好,因为是已经完全渲染好的页面;用户看到首屏的耗时比较小。
前端路由(SPA)
特性:1、根据不同的URL渲染不同的内容;2、不刷新页面(我们只需要把客户端代码部署到cdn上,当没
有与服务端数据进行交互的时候,大可不必访问自己的服务器,这就很大的减轻了服务器的压力)
不仅在页面的交互时页面是不刷新的,就连页面跳转的时候也不刷新页面。
hash可实现前端路由
hash具有如下特性:
1 url中的hash值只是客户端的一种状态,向后端发请求的时候,hash是不会携带的
2. hash改变页面不会刷新
3. hash值的改变,会在浏览器的访问历史中增加记录
4. hash值的更改,通过hashchange事件触发
hash路由基本实现思路如下:
class HashRouter {
constructor() {
this.routes = {};
this.refresh = this.refresh.bind(this)
window.addEventListener('load', this.refresh)
window.addEventListener('hashchange', this.refresh)
}
route(path, cb) {
this.routes[path] = cb || function() {}
}
refresh() {
const path = `/${location.hash.slice(1) || ''}`
const cb = this.routes[path]
cb && cb()
}
}
history路由
hash路由虽然能解决问题,但是带有'#'不太美观, history路由也是一个很不错的选择,但是history路由需要后端配合,使其在访问任何url的时候都返回index.html页面。主要利用的是pushState和popState方法
1. 可以使用Popstate事件来监听url变化
2. pushState和replaceState 并不会触发popState
3. 只有浏览器的前进、后退、history里面的back,forward,go才会触发popState方法。
4. pushState和replaceState方法里面参数相同:
4.1 state: 对象,与网址相关的信息
4.2 title:标题, 有浏览器兼容性问题,一般传null
4.3 网址
history路由基本实现思路如下:
class HistoryRouter {
constructor() {
this.routes = {}
this.bindExecCallbackByPath = this.execCallbackByPath.bind(this)
this.bindPopState = this.popState.bind(this)
this.bindPopState()
this.init(location.pathname)
}
init(path) {
window.history.replaceState({path}, null, path)
this.bindExecCallbackByPath(path)
}
route(path, cb) {
this.routes[path] = cb
}
go(path){
window.history.pushState({
path
}, null, path)
this.bindExecCallbackByPath(path)
}
popState() {
window.addEventListener('popstate', e => {
const path = e.state && e.state.path;
this.bindExecCallbackByPath(path)
})
}
execCallbackByPath(path) {
// 执行回调函数
const cb = this.routes[path]
cb && cb()
}
}
上面所述就是前端路由的基本原理,vueRouter也是基于这几个api实现的,当然了我这里每个路由对应的是一个change方法,vueRouter中每个路由对应的是一个Component. 关于vueRouter的常见问题 vueRouter在一个长列表中选中一个栏目查看详情,从详情中返回的时候,如何保持停留在原来浏览的地方?
- keep-alive
- localStorage/sessionStorage + scrollTop + scrollTo
- scrollBehavior 需要注意的是 scrollBehavior router-link的时候是不会触发的, 点击浏览器的前进/后退或者调用history api的时候才会出发