Hash 模式和 History 模式的区别
表现形式的区别
- Hash 模式 :https://music.163.com/#/paylist?id=3102961863
- History 模式:https://music.163.com/platlist/310293102961863
原理的区别
- Hash 模式是基于锚点,以及 onhaschange 事件
- History 模式是基于 HTML5 中的 History API
history.pushState() IE 10 以后才支持
history.replaceState()
History 模式
- History 需要服务器的支持
- 单页应用中,服务端不存在 http://www.testurl.com/login 这样的地址会返回找不到该页面
- 在服务端应该除了静态资源外部都返回单页应用的 index.html
History 模式 - nginx. 服务器配置
- 从官网下载 nginx 的压缩包
- 把压缩包解压到 C 盘根目录,c:\nginx-1.18.0 文件夹
- 打开命令行,切换到目录 c:\nginx-1.18.0
VueRouter 实现原理
Vue 前置知识
- 插件
- 混入
- Vue.observable()
- 插槽
- render 函数
- 运行时和完整版的 Vue
History 模式
- 通过 history.pushState() 方法改变地址栏
- 监听 popstate 事件
- 根据当前路由地址找到对应组件重新渲染
//模拟 vue-route原理
let _Vue = null
export default class VueRouter {
static install (Vue) {
//1、判断当前插件是否已经安装
if (VueRouter.install.installed) {
return
}
VueRouter.install.installed = true
//2、把 Vue 构造函数记录到全局变量
_Vue = Vue
//3、把创建 Vue 实例时传入的 router对象传入到 Vue实例上
// 混入
_Vue.mixin({
beforeCreate () {
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor (options) {
this.options = options
this.routeMap = {}
this.data = _Vue.observable({
current:'/'
})
}
init () {
this.createRouteMap()
this.initComponents(_Vue)
this.initEvent()
}
createRouteMap () {
//遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap中
this.options.routes.forEach(route => {
this.routeMap[route.path] = route.component
})
}
initComponents (Vue) {
Vue.component('route-link', {
props: {
to:String
},
render (h) {
return h('a', {
attrs:{
href:this.to
},
on: {
click: this.clickHandler
}
}, [this.$slots.default])
},
methods: {
clickHandler (e) {
history.pushState({}, '', this.to) //改变地址栏的内容
this.$router.data.current = this.to //获取当前的地址
e.preventDefault()
}
}
// template:'<a :href="to"><slot></sllot></a>'
})
const self = this
Vue.component('router-link', {
render (h) {
const component = self.routeMap[self.data.current]
return h(component)
}
})
}
initEvent () {
window.addEventListener('popstate', () => {
this.data.current = window.location.pathname
})
}
}