成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Vue編譯器解析compile源碼解析

3403771864 / 388人閱讀

  現(xiàn)在我們講compileToFunctions 的使用方法,現(xiàn)在看看內(nèi)容:

  // compile
  var compiled = compile(template, options);

  其實(shí)真正應(yīng)該講的就是 compile 函數(shù)。

  解析 compile

  上述代碼在調(diào)用 compile ,其中模板字符串 template ,就是讓選項(xiàng)參數(shù) options 的第二個(gè)參數(shù)傳遞給 compile 函數(shù),下面就是有關(guān)傳遞過(guò)去的options如下:

  {
  shouldDecodeNewlines,
  shouldDecodeNewlinesForHref,
  delimiters,
  comments,
  warn
  }

  compile 源碼

  現(xiàn)在我們看看 compile 的源碼。

  function createCompilerCreator(baseCompile) {
  return function createCompiler(baseOptions) {
  function compile(
  template,
  options
  ) {
  var finalOptions = Object.create(baseOptions);
  var errors = [];
  var tips = [];
  finalOptions.warn = function(msg, tip) {
  (tip ? tips : errors).push(msg);
  };
  if (options) {
  // merge custom modules
  if (options.modules) {
  finalOptions.modules =
  (baseOptions.modules || []).concat(options.modules);
  }
  // merge custom directives
  if (options.directives) {
  finalOptions.directives = extend(
  Object.create(baseOptions.directives || null),
  options.directives
  );
  }
  // copy other options
  for (var key in options) {
  if (key !== 'modules' && key !== 'directives') {
  finalOptions[key] = options[key];
  }
  }
  }
  var compiled = baseCompile(template, finalOptions); {
  errors.push.apply(errors, detectErrors(compiled.ast));
  }
  compiled.errors = errors;
  compiled.tips = tips;
  return compiled
  }
  return {
  compile: compile,
  compileToFunctions: createCompileToFunctionFn(compile)
  }
  }
  }

  ·首先可以看到:

  var finalOptions = Object.create(baseOptions);

  配置選項(xiàng)

  finalOptions的配置上的選項(xiàng)最終是要掛載在指定對(duì)象上,其中baseOptions包含編譯器在運(yùn)作的時(shí)候所需的配置選項(xiàng)。

  var baseOptions = {
  expectHTML: true,
  modules: modules$1,
  directives: directives$1,
  isPreTag: isPreTag,
  isUnaryTag: isUnaryTag,
  mustUseProp: mustUseProp,
  canBeLeftOpenTag: canBeLeftOpenTag,
  isReservedTag: isReservedTag,
  getTagNamespace: getTagNamespace,
  staticKeys: genStaticKeys(modules$1)
  };

  屬性分別解析

  第一個(gè)屬性: expectHTML 被設(shè)置為 true 。

  第二個(gè)屬性:modules

  var modules$1 = [
  klass$1,
  style$1,
  model$1
  ];
  var klass$1 = {
  staticKeys: ['staticClass'],
  transformNode: transformNode,
  genData: genData
  };
  var style$1 = {
  staticKeys: ['staticStyle'],
  transformNode: transformNode$1,
  genData: genData$1
  };
  var model$1 = {
  preTransformNode: preTransformNode
  };

  我們一起來(lái)細(xì)細(xì)將屬性:

  第三個(gè)屬性:directives 值是三個(gè)屬性 (model、text、html) 的對(duì)象,且屬性的值都是函數(shù)。

  第四個(gè)屬性:isPreTag 它是一個(gè)函數(shù),其作用是通過(guò)給定的標(biāo)簽名字檢查標(biāo)簽是否是 'pre' 標(biāo)簽。

  第五個(gè)屬性:isUnaryTag 是一個(gè)通過(guò)makeMap生成的函數(shù),該函數(shù)的作用是檢測(cè)給定的標(biāo)簽是否是一元標(biāo)簽。

  第六個(gè)屬性:mustUseProp 它是一個(gè)函數(shù),其作用是用來(lái)檢測(cè)一個(gè)屬性在標(biāo)簽中是否要使用props進(jìn)行綁定。

  第七個(gè)屬性:canBeLeftOpenTag 一個(gè)使用makeMap生成的函數(shù),它的作用是檢測(cè)非一元標(biāo)簽,但卻可以自己補(bǔ)全并閉合的標(biāo)簽。比如 div 標(biāo)簽是一個(gè)雙標(biāo)簽,你需要這樣使用<div> text </div>,但是你依然可以省略閉合標(biāo)簽,直接這樣寫(xiě):<div> text ,且瀏覽器會(huì)自動(dòng)補(bǔ)全。但是有些標(biāo)簽?zāi)悴豢梢赃@樣用,它們是嚴(yán)格的雙標(biāo)簽。

  第八個(gè)屬性:isReservedTag 它是一個(gè)函數(shù),其作用是檢查給定的標(biāo)簽是否是保留的標(biāo)簽。

  第九個(gè)屬性:getTagNamespace 它也是一個(gè)函數(shù),其作用是獲取元素(標(biāo)簽)的命名空間。

  第十個(gè)屬性:staticKeys 它的值是通過(guò)以 modules 為參數(shù)調(diào)用 genStaticKeys 函數(shù)的返回值得到的。 其作用是根據(jù)編譯器選項(xiàng)的 modules 選項(xiàng)生成一個(gè)靜態(tài)鍵字符串。

  我們接下來(lái)繼續(xù)看看baseOptions 中各個(gè)屬性的作用,看看源代碼。

  繼續(xù)往下看:

  var errors = [];
  var tips = [];
  finalOptions.warn = function(msg, tip) {
  (tip ? tips : errors).push(msg);
  };

  finalOptions添加warn 方法

  我們?cè)趂inalOptions加入warn 方法,有兩個(gè)參數(shù):

  msg 錯(cuò)誤或提示的信息

  tip 用來(lái)標(biāo)示 msg 是錯(cuò)誤還是提示。

  warn選項(xiàng)主要用在編譯過(guò)程中的錯(cuò)誤和提示收集,如果收集的信息是錯(cuò)誤信息就將錯(cuò)誤信息添加到前面定義的errors數(shù)組里,如果是提示信息就將其添加到 tips 數(shù)組里。

  繼續(xù):

  if (options) {
  // merge custom modules
  if (options.modules) {
  finalOptions.modules =
  (baseOptions.modules || []).concat(options.modules);
  }
  // merge custom directives
  if (options.directives) {
  finalOptions.directives = extend(
  Object.create(baseOptions.directives || null),
  options.directives
  );
  }
  // copy other options
  for (var key in options) {
  if (key !== 'modules' && key !== 'directives') {
  finalOptions[key] = options[key];
  }
  }
  }

  上述代碼主要檢查 options 證明存在,options 主要是使用編譯器編譯模板時(shí)傳遞的選項(xiàng)參數(shù),簡(jiǎn)單來(lái)說(shuō)就是為調(diào)用 compileToFunctions 函數(shù)時(shí)傳遞的選項(xiàng)參數(shù)。

  而baseOptions理解為編譯器的默認(rèn)選項(xiàng)或者基本選項(xiàng),options 是用來(lái)提供定制能力的擴(kuò)展選項(xiàng)。上面的代碼主要是將options 對(duì)象柔和到 finalOptions 中。

  現(xiàn)在說(shuō)說(shuō)兩個(gè)特殊的屬性處理

  modules: 假如 options.modules 存在,當(dāng)在 finalOptions 對(duì)象上柔和進(jìn) modules 屬性,想要組合并后的新數(shù)組就要用baseOptions.modules 和 options.modules 。

  directives: 對(duì)于directives 采用原型鏈的原理實(shí)現(xiàn)擴(kuò)展屬性對(duì)基本屬性的覆蓋。

  繼續(xù):

  var compiled = baseCompile(template, finalOptions); {
  errors.push.apply(errors, detectErrors(compiled.ast));
  }
  compiled.errors = errors;
  compiled.tips = tips;

  上面的代碼調(diào)用了 baseCompile 函數(shù),并分別將字符串模板(template),以及最終的編譯器選項(xiàng)(finalOptions)傳遞了過(guò)去。

  compiled 是 baseCompile 對(duì)模板的編譯結(jié)果因此上面代碼就是為了讓用通過(guò)抽象語(yǔ)法樹(shù)來(lái)證明是否有存在錯(cuò)誤表達(dá),當(dāng)利用 detectErrors 函數(shù)實(shí)現(xiàn),利用compiled.ast 作為參數(shù)傳遞給 detectErrors 函數(shù),最終就會(huì)返會(huì)一個(gè)包含所有錯(cuò)誤數(shù)值的集合,最終通過(guò)這句代碼將錯(cuò)誤添加到errors。

  將收集到的錯(cuò)誤(errors)和提示(tips)添加到compiled上并返回。

  baseCompile 函數(shù)是在 createCompilerCreator 函數(shù)調(diào)用時(shí)傳遞的實(shí)參。

  // `createCompilerCreator` allows creating compilers that use alternative
  // parser/optimizer/codegen, e.g the SSR optimizing compiler.
  // Here we just export a default compiler using the default parts.
  var createCompiler = createCompilerCreator(function baseCompile(
  template,
  options
  ) {
  var ast = parse(template.trim(), options);
  if (options.optimize !== false) {
  optimize(ast, options);
  }
  var code = generate(ast, options);
  return {
  ast: ast,
  render: code.render,
  staticRenderFns: code.staticRenderFns
  }
  });

  現(xiàn)在內(nèi)容也基本上述完畢,后續(xù)更多精彩內(nèi)容請(qǐng)多多關(guān)注。


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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/127805.html

相關(guān)文章

  • VUE源碼--目錄結(jié)構(gòu)(一)

    摘要:源碼目錄結(jié)構(gòu)打包相關(guān)的配置文件,其中最重要的是。主要是根據(jù)不同的入口,打包為不同的文件。這個(gè)目錄下的代碼邏輯會(huì)把文件內(nèi)容解析成一個(gè)的對(duì)象。 源碼目錄結(jié)構(gòu) VUE 2.6.10 ├── scripts # 打包相關(guān)的配置文件,其中最重要的是config.js。主要是根據(jù)不同的入口,打 包為不同的文件。 ├── dist # 打包之后文...

    tuniutech 評(píng)論0 收藏0
  • Vue原理】Compile - 源碼版 之 從新建實(shí)例到 compile結(jié)束的主要流程

    摘要:頁(yè)面這個(gè)實(shí)例,按理就需要解析兩次,但是有緩存之后就不會(huì)理清思路也就是說(shuō),其實(shí)內(nèi)核就是不過(guò)是經(jīng)過(guò)了兩波包裝的第一波包裝在中的內(nèi)部函數(shù)中內(nèi)部函數(shù)的作用是合并公共和自定義,但是相關(guān)代碼已經(jīng)省略,另一個(gè)就是執(zhí)行第二波包裝在中,目的是進(jìn)行緩存 寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 ...

    CODING 評(píng)論0 收藏0
  • vue-loader 源碼解析系列之 整體分析

    摘要:筆者系貢獻(xiàn)者之一官方說(shuō)明簡(jiǎn)單來(lái)說(shuō)就是將文件變成,然后放入瀏覽器運(yùn)行。部分首先分析部分從做右到左,也就是被先后被和處理過(guò)了。源碼解析之二源碼解析之三寫(xiě)作中源碼解析之四寫(xiě)作中作者博客作者微博 筆者系 vue-loader 貢獻(xiàn)者(#16)之一 官方說(shuō)明 vue-loader is a loader for Webpack that can transform Vue components ...

    icattlecoder 評(píng)論0 收藏0
  • 太原面經(jīng)分享:如何在vue面試環(huán)節(jié),展示你晉級(jí)阿里P6+的技術(shù)功底?

    摘要:假如你通過(guò)閱讀源碼,掌握了對(duì)的實(shí)現(xiàn)原理,對(duì)生態(tài)系統(tǒng)有了充分的認(rèn)識(shí),那你會(huì)在面試環(huán)節(jié)游刃有余,達(dá)到晉級(jí)阿里的技術(shù)功底,從而提高個(gè)人競(jìng)爭(zhēng)力,面試加分更容易拿。 前言 一年一度緊張刺激的高考開(kāi)始了,與此同時(shí),我也沒(méi)閑著,奔走在各大公司的前端面試環(huán)節(jié),不斷積累著經(jīng)驗(yàn),一路升級(jí)打怪。 最近兩年,太原作為一個(gè)準(zhǔn)二線城市,各大互聯(lián)網(wǎng)公司的技術(shù)棧也在升級(jí)換代,假如你在太原面試前端崗位,而你的技術(shù)庫(kù)里若...

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

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

0條評(píng)論

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