hash 模式原理
获取 hash
url 的 # 的值是可以通过 window.location.hash 来获取和修改
监听 hash 改变
onhashchange
window.addEventListener('hashchange', () => {console.log('hash: ', location.hash);})
通过知道 hash 的变化,来决定渲染哪个组件
history 模式原理
后端需要做的是无论访问怎样的 URL 都返回 index.html,后续交给前端来管理
前端通过 pushState 切换各个不同的路由,渲染不同的组件
获取路径
通过 window.location.pathname 来获取
切换路由
history.pushState({name:'user'}, '', user);
监听路径变化
popstate,监听当使用前进后退使路由发生改变
window.addEventListener('popstate', () => {console.log(location.pathname)})
简单实现
render 函数的使用
h (标签, {options}, children)
options
{class: { },style: { },attrs: { }, // html属性props: { }, // 组件propsdomProps: { }, // DOM属性on: {},nativeOn: {},directives: [], // 自定义指令scopedSlots: {} // 作用域slot}
利用 Vue 实例 vm 的数据响应,在 hashChange 修改 vm.currentPath
使 router-view 组件渲染对应 route options 中所设置的 componentlet Vue;export default class {constructor(options) {this.$options = options;this.routeMap = {};this.vm = new Vue({data() {return {currentPath: '/'}}});}init() {this.bindEvent();this.createRouteMap();this.initRouteComponent();}bindEvent() {window.addEventListener('DOMContentLoaded', this.handleHashChange.bind(this));window.addEventListener('hashchange', this.handleHashChange.bind(this));}initRouteComponent() {Vue.component('router-view', {render: h => {const component = this.routeMap[this.vm.currentPath].component;return h(component);}});Vue.component('router-link', {render(h) {return h('a', { attrs: { href: "/#" + this.$attrs.to } }, this.$slots.default);}});}createRouteMap() {this.$options.routes.forEach(item => {this.routeMap[item.path] = item;})}getHashValue() {return window.location.hash.slice(1);}handleHashChange() {const hash = this.getHashValue();this.vm.currentPath = hash;}static install(_Vue) {Vue = _Vue;Vue.mixin({beforeCreate() {if (this.$options.router) {this.$options.router.init();}}})}}
