1. Hash和History的区别
- 表现形式的不同:Hash带#号
- 原理的区别
- 1.Hash模式是基于锚点,以及onhashchange事件。通过锚点的值,作为路由地址,当地址发生变化后,触发onhashchange事件。根据路径决定页面上实现的内容
- 2.history模式是基于HTML5中的 History API
- history.pushState() IE10以后才支持
- History.replaceState()
2.History模式的使用
const path = require('path')
const history = require('connect-history-api-fallback')
const express = require('express')
const app = express()
app.use(history())
app.use(express.static(path.join(__dirname, '../web')))
app.listen(3000, () => {
console.log('服务器开启,端口:3000')
})
- nginx服务器配置,修改nginx.conf配置文件
location / {
root html;
index index.html index.htm;
try_files $uri $uri/ /index.hmtl
}
3.简单模仿实现history模式的VueRouter
Vue.use(VueRouter)
const router = new VueRouter({
routes:[
{name: 'home', path: '/', component: homeCpn}
]
})
new Vue({
router,
render: h => h(App)
}).$mount('#app')
<tempalte>
<div id="app">
<div class="nav">
<router-link to="/">home</router-link>
<router-link to="/about">about</router-link>
</div>
<router-view></router-view>
</div>
</tempalte>
let _Vue = null;
class VueRouter {
static install(Vue) {
if (VueRouter.install.installed) {
return;
}
VueRouter.install.installed = true;
_Vue = Vue;
_Vue.mixin({
beforeCreate() {
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router;
}
}
});
}
constructor(options) {
this.options = options;
this.routeMap = {};
this.data = _Vue.observable({
current: "/"
});
this.init();
}
init() {
this.createRouteMap();
this.initComponent(_Vue);
this.initEvent();
}
createRouteMap() {
this.options.routes.forEach(route => {
this.routeMap[route.path] = route.component;
});
}
initComponent(Vue) {
Vue.component("router-link", {
props: {
to: String
},
render(h) {
return h(
"a",
{
attrs: {
href: this.to
},
on: {
click: this.clickhander
}
},
[this.$slots.default]
);
},
methods: {
clickhander(e) {
history.pushState({}, "", this.to);
this.$router.data.current = this.to;
e.preventDefault();
}
}
});
const self = this;
Vue.component("router-view", {
render(h) {
const cm = self.routeMap[self.data.current];
return h(cm);
}
});
}
initEvent() {
window.addEventListener("popstate", () => {
this.data.current = window.location.pathname;
});
}
}