首頁 > 軟體

Vue Router中Matcher的初始化流程

2022-04-15 10:01:41

Matcher

createMatcher()的初始化

瞭解相關的幾個概念

1、Location型別

對url的結構化描述。比如url = “/main?p1=1&p2=2222&p3=3333”,它的path就是“ /main” , query 是{ p1:1, p2:222, p3:333 }

declare type Location = {
  _normalized?: boolean;
  name?: string;
  path?: string;
  hash?: string;
  query?: Dictionary<string>;
  params?: Dictionary<string>;
  append?: boolean;
  replace?: boolean;
}

2、rowLocation型別

declare type RawLocation = string | Location  //除了是Location型別還可以是字串

3、Route型別

表示一條路由,屬性也包括path、query、hash等。重要的是mached它表示匹配到的所有的 RouteRecord 物件。

declare type Route = {
  path: string;
  name: ?string;
  hash: string;
  query: Dictionary<string>;
  params: Dictionary<string>;
  fullPath: string;
  matched: Array<RouteRecord>;
  redirectedFrom?: string;
  meta?: any;
}

4、RouteRecord型別

declare type RouteRecord = {
  path: string;
  regex: RouteRegExp;
  components: Dictionary<any>;
  instances: Dictionary<any>;   //表示元件的範例 一個物件型別
  name: ?string;
  parent: ?RouteRecord;  //表示父的 RouteRecord 
  redirect: ?RedirectOption;
  matchAs: ?string;
  beforeEnter: ?NavigationGuard;
  meta: any;
  props: boolean | Object | Function | Dictionary<boolean | Object | Function>;
}
  • matcher物件對外提供 match() 和 addRoutes()兩個方法。
  • addRoutes() 作用是動態新增路由設定。
  • match() 根據傳入的rawLoction型別的raw 和當前的路徑 currentRoute 計算出一個新的路徑並返回。

addRoutes()的實現

  • 是呼叫createRouteMap()目標是把使用者的路由設定轉成一張路由對映表。方法中遍歷路由設定routes, 返回值是一個包括 pathList 、pathMap 、nameMap的物件。
  • pathList是儲存所有path值,pathMap 表示一個path到RouteRecord的對映關係,nameMap 表示name到RouteRecord的對映關係。
//記錄path 及 path到RouteRecord的對映
if (!pathMap[record.path]) {
    pathList.push(record.path)  //  ['/aaa/bbb','/cccc/ddd']
    pathMap[record.path] = record  //path值作為key 
    //  /aaa/bbb:{ path:"/aaa/bbb" ,regex : //}
}

pathMap值範例 

//記錄name到RouteRecord的對映;  name值作為key
if (name) {
    if (!nameMap[name]) {
      nameMap[name] = record
    } else if (process.env.NODE_ENV !== 'production' && !matchAs) {
      warn(
        false,
        `Duplicate named routes definition: ` +
          `{ name: "${name}", path: "${record.path}" }`
      )
    }
  }

得到的這些map是為了路由匹配做了基礎。

match()

作用是匹配一個路徑並找到對映的元件。

執行過程

  • 先normalizeLocation,得到一個標準化的定位描述location{ _normalized: true, path:"/foo", query:{}, hash:"" }
  • (1)name存在時,通過name從nameMap中拿到路由記錄record,接著處理記錄record中的引數。將location、record和vueRouter物件作為引數傳入到createRoute()中生成一個新的route路徑。
  • (2)name不存在而path值存在,遍歷路徑集合pathList,由取到的record和location匹配路由。如果匹配就去生成一個新路徑。

matched屬性

在VueRouter中,所有的Route 最終都是通過 createRoute 函數建立,並且它最後是不可以被外部修改的。 Route物件中有一個重要屬性 matched,它通過 formatMatch(record) 計算得到:

function formatMatch (record: ?RouteRecord): Array<RouteRecord> {
  const res = []
  while (record) {
    res.unshift(record)
    record = record.parent
  }
  return res
}

record迴圈往上找parent,直到找到最外層。把所有的record都放到一個陣列裡面,它記錄了一條線路上的所有record。matched屬性為之後渲染元件提供了依據。

總結

  • createMatcher的初始化就是根據路由的匹配建立路徑、名稱到路由記錄的對映表。
  • match會根據傳入的位置和路徑計算新的位置,並匹配到對應的路由記錄,然後根據新的位置和記錄建立新的route路徑。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。 


IT145.com E-mail:sddin#qq.com