hash 模式原理

获取 hash

url 的 # 的值是可以通过 window.location.hash 来获取和修改

监听 hash 改变

onhashchange

  1. window.addEventListener('hashchange', () => {
  2. console.log('hash: ', location.hash);
  3. })

通过知道 hash 的变化,来决定渲染哪个组件

history 模式原理

后端需要做的是无论访问怎样的 URL 都返回 index.html,后续交给前端来管理
前端通过 pushState 切换各个不同的路由,渲染不同的组件

获取路径

通过 window.location.pathname 来获取

切换路由

history.pushState({name:'user'}, '', user);

监听路径变化

popstate,监听当使用前进后退使路由发生改变

  1. window.addEventListener('popstate', () => {
  2. console.log(location.pathname)
  3. })

简单实现

render 函数的使用
h (标签, {options}, children)

  • options

    1. {
    2. class: { },
    3. style: { },
    4. attrs: { }, // html属性
    5. props: { }, // 组件props
    6. domProps: { }, // DOM属性
    7. on: {},
    8. nativeOn: {},
    9. directives: [], // 自定义指令
    10. scopedSlots: {} // 作用域slot
    11. }

    利用 Vue 实例 vm 的数据响应,在 hashChange 修改 vm.currentPath
    使 router-view 组件渲染对应 route options 中所设置的 component

    1. let Vue;
    2. export default class {
    3. constructor(options) {
    4. this.$options = options;
    5. this.routeMap = {};
    6. this.vm = new Vue({
    7. data() {
    8. return {
    9. currentPath: '/'
    10. }
    11. }
    12. });
    13. }
    14. init() {
    15. this.bindEvent();
    16. this.createRouteMap();
    17. this.initRouteComponent();
    18. }
    19. bindEvent() {
    20. window.addEventListener('DOMContentLoaded', this.handleHashChange.bind(this));
    21. window.addEventListener('hashchange', this.handleHashChange.bind(this));
    22. }
    23. initRouteComponent() {
    24. Vue.component('router-view', {
    25. render: h => {
    26. const component = this.routeMap[this.vm.currentPath].component;
    27. return h(component);
    28. }
    29. });
    30. Vue.component('router-link', {
    31. render(h) {
    32. return h('a', { attrs: { href: "/#" + this.$attrs.to } }, this.$slots.default);
    33. }
    34. });
    35. }
    36. createRouteMap() {
    37. this.$options.routes.forEach(item => {
    38. this.routeMap[item.path] = item;
    39. })
    40. }
    41. getHashValue() {
    42. return window.location.hash.slice(1);
    43. }
    44. handleHashChange() {
    45. const hash = this.getHashValue();
    46. this.vm.currentPath = hash;
    47. }
    48. static install(_Vue) {
    49. Vue = _Vue;
    50. Vue.mixin({
    51. beforeCreate() {
    52. if (this.$options.router) {
    53. this.$options.router.init();
    54. }
    55. }
    56. })
    57. }
    58. }