国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Vue源碼解析(六)-vue-router

蘇丹 / 2548人閱讀

摘要:是響應(yīng)式的,當(dāng)瀏覽器路由改變時(shí),的值也會(huì)相應(yīng)的改變的作用是清楚了,但頁面內(nèi)容的變化是怎么實(shí)現(xiàn)的呢下面再介紹下的作用。

先上一段簡單的demo,本文根據(jù)此demo進(jìn)行解析

Vue.use(VueRouter)
const router = new VueRouter({
    routes: [
        { path: "/home", component: {template: "
home
"}} ] }) new Vue({ "el":"#app", router, template: `

Basic

` })

vue源碼解析(五)中介紹過,Vue.use(VueRouter)其實(shí)主要調(diào)用了VueRouter.install(Vue)方法

function install (Vue) {
  //掛載全局的鉤子函數(shù)到Vue,vue對(duì)象初始化會(huì)調(diào)用下面的函數(shù)
  Vue.mixin({
    beforeCreate: function beforeCreate () {
      if (isDef(this.$options.router)) {
        // _routerRoot為當(dāng)前vue對(duì)象
        this._routerRoot = this;
        // _router為new Vue傳入的VueRouter對(duì)象
        this._router = this.$options.router;
        //調(diào)用 VueRouter.protoype.init,后面介紹
        this._router.init(this);
        // 設(shè)置響應(yīng)式的_route,this._router.history.current為當(dāng)前頁面的路由信息
        Vue.util.defineReactive(this, "_route", this._router.history.current);
      } else {
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
      }
    }
  });
  //全局注冊(cè)組件
  Vue.component("router-view", View);
  Vue.component("router-link", Link);
}
// 全局組件router-view的參數(shù)
var View = {
  name: "router-view",
  functional: true,
  props: {
    name: {
      type: String,
      default: "default"
    }
  },
  render: function render (_, ref){}
}

install方法主要是掛載鉤子函數(shù)和全局注冊(cè)組件,全局注冊(cè)的組件router-view的值如下,

再看一下router = new VueRouter的過程

var VueRouter = function VueRouter (options) {
  this.options = options;
  //默認(rèn)使用hash進(jìn)行前端路由
  var mode = options.mode || "hash";
  switch (mode) {
    case "history":
      this.history = new HTML5History(this, options.base);
      break
    case "hash":
      this.history = new HashHistory(this, options.base, this.fallback);
      break
  }
}
//  HashHistory 和 HTML5History都是繼承History
var HashHistory = (function (History$$1) {
  function HashHistory (router, base, fallback) {
    History$$1.call(this, router, base);
  }

  if ( History$$1 ) HashHistory.__proto__ = History$$1;
  HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
  HashHistory.prototype.constructor = HashHistory;
  return HashHistory;
}(History));

var History = function History (router, base) {
  // VueRouter實(shí)例對(duì)象
  this.router = router;
  //base路徑
  this.base = normalizeBase(base);
  //當(dāng)前路由信息,此時(shí)是一個(gè)空值
  this.current = START;
};

new Vue的過程中會(huì)觸發(fā)掛載的beforeCreate函數(shù),主要是調(diào)用了this._router.init(this);
為了更清晰的解析整個(gè)流程,假定我們現(xiàn)在訪問的頁面路徑是/home,并且是hash的方式進(jìn)行路由

VueRouter.prototype.init = function init (app /* Vue component instance */) {
  var history = this.history;

  if (history instanceof HTML5History) {
    history.transitionTo(history.getCurrentLocation());
  } else if (history instanceof HashHistory) {
    var setupHashListener = function () {
      //監(jiān)聽瀏覽器地址的變更,并調(diào)用transitionTo“跳轉(zhuǎn)”到新的路由頁面
      history.setupListeners();
    };
    //初始化時(shí)調(diào)用一次transitionTo,根據(jù)當(dāng)前瀏覽器地址欄里的path(/home)來激活對(duì)應(yīng)的路由
    history.transitionTo(
      // 初始化值為“/home”
      history.getCurrentLocation(),
      setupHashListener    
    );
  }
};
HashHistory.prototype.setupListeners = function setupListeners () {
   //監(jiān)聽瀏覽器地址的變更
   window.addEventListener(supportsPushState ? "popstate" : "hashchange", function () {
      //實(shí)現(xiàn)頁面內(nèi)容的變更,getHash()為變更后的hash路徑
      this$1.transitionTo(getHash())
   }
}
//將頁面轉(zhuǎn)換到當(dāng)前真實(shí)的路由
History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
  var this$1 = this;
  // 根據(jù)location("/home")得到route對(duì)象{name: undefined, meta: {…}, path: "/home", hash: "", query: {…},?…}
  var route = this.router.match(location, this.current);
  //confirmTransition實(shí)現(xiàn)比較復(fù)雜,本文不做介紹,主要會(huì)執(zhí)行下面的回調(diào)函數(shù)
  this.confirmTransition(route, function () {
    //將histoty.current值更新為route
    this$1.updateRoute(route);
    //執(zhí)行onComplete(setupHashListener)
    onComplete && onComplete(route);
    //更新瀏覽器url地址
    this$1.ensureURL();
  }
};

function match (){
  遍歷路由配置(本文只有一項(xiàng)配置{ path: "/home", component: {template: "
home
"}}) for (var i = 0; i < pathList.length; i++) { var path = pathList[i]; var record$1 = pathMap[path]; //判斷當(dāng)前路徑是否有匹配的路由配置 if (matchRoute(record$1.regex, location.path, location.params)) { return _createRoute(record$1, location, redirectedFrom) } } // no match return _createRoute(null, location) } function createRoute (record){ var route = { name: location.name || (record && record.name), meta: (record && record.meta) || {}, path: location.path || "/", hash: location.hash || "", query: query, params: location.params || {}, fullPath: getFullPath(location, stringifyQuery$$1), //當(dāng)前路徑匹配的路由配置 matched: record ? formatMatch(record) : [] }; return Object.freeze(route) }

根據(jù)上面的代碼邏輯可以分析得出,vue對(duì)象初始化時(shí)會(huì)掛載屬性vm._router(記錄了整個(gè)應(yīng)用的路由配置信息)和vm._route(記錄了當(dāng)前的路由信息)。vm._route是響應(yīng)式的,當(dāng)瀏覽器路由改變時(shí),vm._route的值也會(huì)相應(yīng)的改變
vm._route的作用是清楚了,但頁面內(nèi)容的變化是怎么實(shí)現(xiàn)的呢?下面再介紹下router-view的作用。
Vue源碼解析(四)-components組件介紹過,vue初始化時(shí)根據(jù)template函數(shù)生成render函數(shù),本文render函數(shù)會(huì)調(diào)用vm._c("router-view"),_createElement判斷router-view是注冊(cè)過的組件,因此以組件的方式生成vnode,但是router-view生成vnode的過程與Vue源碼解析(四)中的方法又有區(qū)別

function _createElement(){
    //本例tag=‘router-view’,‘router-view’在components屬性中注冊(cè)過,因此以組件的方式生成vnode
    if (isDef(Ctor = resolveAsset(context.$options, "components", tag))) {
      //Ctor是router-view的構(gòu)造函數(shù)VueComponent(Vue.component("router-view", View)注冊(cè))
      vnode = createComponent(Ctor, data, context, children, tag);
    }
}

function createComponent (Ctor){
    //Ctor 此時(shí)已經(jīng)是構(gòu)造函數(shù) , 不需要再調(diào)用Vue.extend生成
    var baseCtor = context.$options._base;
    if (isObject(Ctor)) {
      Ctor = baseCtor.extend(Ctor);
    }
    // router-view是functional component(見上文圖中view的option的值),與用戶自定義的component的vnode生成方法有區(qū)別
    if (isTrue(Ctor.options.functional)) {
      return createFunctionalComponent(Ctor, propsData, data, context, children)
    }
    //用戶自定義component的vnode構(gòu)造方法
    var vnode = new VNode(
      ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : "")),
      data, undefined, undefined, undefined, context,
      { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children:         children } );
}

function createFunctionalComponent (Ctor){
   var options = Ctor.options;
   //主要是調(diào)用View.render方法,前文提到過
   var vnode = options.render.call(null, renderContext._c, renderContext);
   return vnode;
}

var View = {
  name: "router-view",
  functional: true,
  props: {
    name: {
      type: String,
      default: "default"
    }
  },
  render: function render (_, ref) {
    //Vue實(shí)例化對(duì)象vm
    var parent = ref.parent;
    // vm._route
    var route = parent.$route;

    var depth = 0;
    //上文提到的createRoute中生成的路由匹配信息
    var matched = route.matched[depth];
    
    // _createElement方法
    var h = parent.$createElement;
    // render empty node if no matched route
    if (!matched) {
      return h()
    }
    // 本文component為{template: "
home
", _Ctor: {…}, inject: {…}} var component = matched.components[name]; //重新調(diào)用_createElement,這次是以常規(guī)方式生成vnode,后續(xù)vnode將渲染成template中的內(nèi)容 return h(component, data, children) } };

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/90405.html

相關(guān)文章

  • 關(guān)于Vue2一些值得推薦的文章 -- 五、月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

    sutaking 評(píng)論0 收藏0
  • 關(guān)于Vue2一些值得推薦的文章 -- 五、月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

    khs1994 評(píng)論0 收藏0
  • 【轉(zhuǎn)】使用Vue-Router 2實(shí)現(xiàn)路由功能

    摘要:請(qǐng)輸入代碼注意只適用于版本,下面我們是基于講的如何使用實(shí)現(xiàn)路由功能。一使用路由在中,需要明確安裝路由功能定義組件,這里使用從其他文件進(jìn)來定義路由創(chuàng)建實(shí)例,然后傳配置創(chuàng)建和掛載根實(shí)例。路由記錄就是配置數(shù)組中的對(duì)象副本還有在數(shù)組。 請(qǐng)輸入代碼注意:vue-router 2只適用于Vue2.x版本,下面我們是基于vue2.0講的如何使用vue-router 2實(shí)現(xiàn)路由功能。推薦使用npm安裝...

    seanlook 評(píng)論0 收藏0
  • Vue.js資源分享

    摘要:中文官網(wǎng)英文官網(wǎng)組織發(fā)出一個(gè)問題之后,不要暫時(shí)的離開電腦,如果沒有把握先不要提問。珍惜每一次提問,感恩每一次反饋,每個(gè)人工作還是業(yè)余之外抽出的時(shí)間有限,充分準(zhǔn)備好應(yīng)有的資源之后再發(fā)問,有利于問題能夠高效質(zhì)量地得到解決。 Vue.js資源分享 更多資源請(qǐng)Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/maid...

    vpants 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<