zoukankan      html  css  js  c++  java
  • 前端路由原理及vue-router介绍

    前端路由原理本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。目前单页面使用的路由就只有两种实现方式

    hash

    history

    www.test.com/##/ 就是 Hash URL,当 ## 后面的哈希值发生变化时,不会向服务器请求数据,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面。

    vue-router hash实现源码(完整源码访问https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js#L22-L54):

    **
     * 添加 url hash 变化的监听器
     */
    setupListeners () {
      const router = this.router
    
      /**
       * 每当 hash 变化时就解析路径
       * 匹配路由
       */
      window.addEventListener('hashchange', () => {
        const current = this.current
        /**
         * transitionTo: 
         * 匹配路由
         * 并通过路由配置,把新的页面 render 到 ui-view 的节点
         */
        this.transitionTo(getHash(), route => {
          replaceHash(route.fullPath)
        })
      })
    }

    检测到 hash 的变化后,就可以通过替换 DOM 的方式来实现页面的更换。

    History 模式是 HTML5 新推出的功能,比之 Hash URL 更加美观

    两个 API ,pushState和replaceState可以改变 url 地址且不会发送请求,还有onpopState事件。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。具体可以访问官网:https://router.vuejs.org/zh/guide/essentials/history-mode.html

    vue-router history实现源码(完整源码访问https://github.com/vuejs/vue-router/blob/dev/src/history/html5.js)

    export class HTML5History extends History {
      constructor (router, base) {
        super(router, base)
        /**
         * 原理还是跟 hash 实现一样
         * 通过监听 popstate 事件
         * 匹配路由,然后更新页面 DOM
         */
        window.addEventListener('popstate', e => {
          const current = this.current
    
          // Avoiding first `popstate` event dispatched in some browsers but first
          // history route not updated since async guard at the same time.
          const location = getLocation(this.base)
          if (this.current === START && location === initLocation) {
            return
          }
    
          this.transitionTo(location, route => {
            if (supportsScroll) {
              handleScroll(router, route, current, true)
            }
          })
        })
      }
    
      go (n) {
        window.history.go(n)
      }
    
      push (location, onComplete, onAbort) {
        const { current: fromRoute } = this
        this.transitionTo(location, route => {
          // 使用 pushState 更新 url,不会导致浏览器发送请求,从而不会刷新页面
          pushState(cleanPath(this.base + route.fullPath))
          onComplete && onComplete(route)
        }, onAbort)
      }
    
      replace (location, onComplete, onAbort) {
        const { current: fromRoute } = this
        this.transitionTo(location, route => {
          // replaceState 跟 pushState 的区别在于,不会记录到历史栈
          replaceState(cleanPath(this.base + route.fullPath))
          onComplete && onComplete(route)
        }, onAbort)
      }
    }
  • 相关阅读:
    js基础之BOM
    js基础之DOM
    js基础之数组
    js基础之arguments、css
    四个使用this的典型应用
    网页优化URI(http URI scheme与data URI scheme)
    FF与IE对JavaScript和CSS的区别
    javascrip自定义对象的方式
    常用的JavaScript验证正则表达式1
    4.26日软件开发日记:今天我干了什么?
  • 原文地址:https://www.cnblogs.com/lhh520/p/10280245.html
Copyright © 2011-2022 走看看