vue-router源码分析(二)--HTML5History

首先: HTML5History也继承自History

var HTML5History = (function(History$$1){...})(History)
function getLocation (base) { //处理url
  var path = decodeURI(window.location.pathname);
  if (base && path.indexOf(base) === 0) {
    path = path.slice(base.length);
  }
  return (path || '/') + window.location.search + window.location.hash
}

HTML5History构造方法,window监听popstate来触发组件切换和历史记录更新

function HTML5History (router, base) {
    var this$1 = this;

    History$$1.call(this, router, base); //执行History构造方法,继承实例方法
    //滚动处理
    var expectScroll = router.options.scrollBehavior;
    var supportsScroll = supportsPushState && expectScroll;

    if (supportsScroll) {
      setupScroll();
    }
    //获取初始url
    var initLocation = getLocation(this.base);
    //给window添加popstate事件监听
    window.addEventListener('popstate', function (e) {
      var current = this$1.current;
      
      // Avoiding first `popstate` event dispatched in some browsers but first
      // history route not updated since async guard at the same time.
      var location = getLocation(this$1.base);
      if (this$1.current === START && location === initLocation) {
        return
      }
        //调用transitionTo方法,完成跳转
      this$1.transitionTo(location, function (route) {
        if (supportsScroll) {
          handleScroll(router, route, current, true);
        }
      });
    });
  }

原型方法: 

1. HTML5History.prototype.go  调用window.history.go()方法

2. HTML5History.prototype.push  调用实例方法transitionTo,回调中执行pushState

var ref = this;
    var fromRoute = ref.current;
    this.transitionTo(location, function (route) {
      pushState(cleanPath(this$1.base + route.fullPath));
      handleScroll(this$1.router, route, fromRoute, false);
      onComplete && onComplete(route);
    }, onAbort);

3. HTML5History.prototype.replace 同上。调用实例方法transitionTo,回调中执行replaceState

4.HTML5History.prototype.ensureURL 

//如果要跳转的地址跟当前地址不同
if (getLocation(this.base) !== this.current.fullPath) {
      var current = cleanPath(this.base + this.current.fullPath);
    //根据传入的push参数来决定是push还是replace新地址
      push ? pushState(current) : replaceState(current);
    }

pushState, replaceState

function pushState (url, replace) {
  saveScrollPosition();
  // try...catch the pushState call to get around Safari
  // DOM Exception 18 where it limits to 100 pushState calls
  var history = window.history;
  try {
    if (replace) {
      history.replaceState({ key: _key }, '', url);
    } else {
      _key = genKey();
      history.pushState({ key: _key }, '', url);
    }
  } catch (e) {
    window.location[replace ? 'replace' : 'assign'](url);
  }
}

function replaceState (url) {
  pushState(url, true);
}
发布了66 篇原创文章 · 获赞 13 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/haoyanyu_/article/details/87855218