Vue-API之全局配置


API

全局配置

Vue.config 是一個對象,包含 Vue 的全局配置。

  • 源碼位置:util/config.js
  • 搜索config 可以找到其源碼地址,其中聲明了config的類型和默認參數
    下面僅僅留下官方的幾個配置項
export type Config = {
  // user
  optionMergeStrategies: { [key: string]:  Function }; //自定義合並策略的選項。
  silent: boolean; //關於日志和警告
  productionTip: boolean; //設置為 false 以阻止 vue 在啟動時生成生產提示。
  performance: boolean;//設置為 true 以在瀏覽器開發工具的性能/時間線面板中啟用對組件初始化、編譯、渲染和打補丁的性能追蹤。只適用於開發模式和支持 performance.mark API 的瀏覽器上。
  devtools: boolean; //配置是否允許 vue-devtools 檢查代碼。
  errorHandler: ?(err: Error, vm: Component, info: string) => void; //指定組件的渲染和觀察期間未捕獲錯誤的處理函數。這個處理函數被調用時,可獲取錯誤信息和 Vue 實例。
  warnHandler: ?(msg: string, vm: Component, trace: string) => void; //為 Vue 的運行時警告賦予一個自定義處理函數。注意這只會在開發者環境下生效,在生產環境下它會被忽略。
  ignoredElements: Array<string | RegExp>; //使 Vue 忽略在 Vue 之外的自定義元素 
  keyCodes: { [key: string]: number | Array<number> };//給 v-on 自定義鍵位別名

  // platform
  ..... 平台相關
  ......    
};
export default ({默認項}: Config))
  • 分析: 可以看出來整個config是進行了單獨的整體的舉例,然后配置完默認項后暴露出去,那么我們又是如何能夠使用vue.confige.XXX 使用呢。

  • 源碼地址 core/global-api/index.js
import config from '../config'
....
export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  configDef.get = () => config
  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }
  Object.defineProperty(Vue, 'config', configDef)
....
}

-- 分析:,我們在這個文件中可以中看到,Vue在全局注入API 的時候將config注入.依然是用了Object.defineProperty()方法將其放在了Vue實例中。
綜上我能感受到作為大框架對於各種功能的分散和聚合(用詞不當,水平過低),是十分精煉的,組織結構清晰,明了。
那么接下來,看看vue提供的config暴露api大致都是如何工作的吧。

#silent

  • 源碼地址:core/util/debug.js
...
  warn = (msg, vm) => {
    const trace = vm ? generateComponentTrace(vm) : ''

    if (config.warnHandler) {
      config.warnHandler.call(null, msg, vm, trace)
    } else if (hasConsole && (!config.silent)) { //判斷slinet
      console.error(`[Vue warn]: ${msg}${trace}`)
    }
  }

  tip = (msg, vm) => {
    if (hasConsole && (!config.silent)) { // 判斷slient
      console.warn(`[Vue tip]: ${msg}` + (
        vm ? generateComponentTrace(vm) : ''
      ))
    }
  }
...

  • 分析:我們可以看到再debug.js中vue對slient的使用,就是非常常規的判斷,無需多說。

# optionMergeStrategies

  • 源碼地址:core/util/option.js
...
 /**
 * Option overwriting strategies are functions that handle
 * how to merge a parent option value and a child option
 * value into the final value.
 */
const strats = config.optionMergeStrategies
... 做了老多事情
合並各種數據,數據,方法,watch等等

...

  • 分析: optionMergeStrategies主要用於 mixin 以及 Vue.extend() 方法時對於子組件和父組件如果有相同的屬性(option),我們可以看到optionMergeStrategies的使用是在potion中,里面進行了各種合並,因為其中各種類型的合並策略都能拿出來細說,次此梳理,近是淺嘗即止,顧不深究,以后有機會再去討論,Vue方面更深刻的源碼分析,還是先以數據驅動和響應式部分為主。

# devtools

  • 源碼地址:core/observer/scheduler.js & core/util/env.js
/**
 * Flush both queues and run the watchers.
 */
function flushSchedulerQueue () {
    ...
    // devtool hook
  /* istanbul ignore if */
  if (devtools && config.devtools) {
    devtools.emit('flush')
  }
    ....
}
// detect devtools
export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
  • 分析,可以看到devtools是聲明或者定義是在env.js中其實就是window.VUE_DEVTOOLS_GLOBAL_HOOK 這個對象,如果你安裝了這個工具,再控制台打印可以看到
    {_buffer: Array(0), Vue: ƒ, _replayBuffer: ƒ, on: ƒ, once: ƒ, …}。那么其中你就可以看到再scheduler.js中是用的emit的方法, 我們只看對於vue的支持,這個工具的具體實現不考慮;,可以看到他的使用是在flushSchedulerQueue()這個方法中使用,這個方法在注釋中就很清晰,而且這個方法也是vue響應式中很關鍵的方法,這里大致說一下, 再數據派發更新過程中Vue會遍歷我們引入一個隊列概念,這也是 Vue 在做派發更新的時候的⼀個優化的點,它並不會每次數據改
    變都觸發 watcher 的回調,⽽是把這些 watcher 先添加到⼀個隊列⾥,然后在 nextTick 后執⾏flushSchedulerQueue 。其中先后進行了
  1. 隊列排序,queue.sort((a, b) => a.id - b.id)
  2. 隊列遍歷在對 queue 排序后,接着就是要對它做遍歷,拿到對應的 watcher ,執⾏ watcher.run()
  3. 狀態恢復 執⾏ resetSchedulerState 函數,

大致如此,具體細節,又是很冗長繁瑣,如有興趣,可以看我的關於響應式的處理。


# errorHandler

  • 源碼位置 core/util/error.js
function globalHandleError (err, vm, info) {
  if (config.errorHandler) {
    try {
      return config.errorHandler.call(null, err, vm, info) //
    } catch (e) {
      // if the user intentionally throws the original error in the handler,
      // do not log it twice
      if (e !== err) {
        logError(e, null, 'config.errorHandler')
      }
    }
  }
  logError(err, vm, info)
}
  • 這個API其實看官方的文檔就很好理解。

指定組件的渲染和觀察期間未捕獲錯誤的處理函數。這個處理函數被調用時,可獲取錯誤信息和 Vue 實例。

此處感覺沒啥說的,,,,網上看到有分析的很多的,我就不細究了有興趣可以
點擊這里


# warnHandler

  • 源碼位置 core/util/error.js
 warn = (msg, vm) => {
    const trace = vm ? generateComponentTrace(vm) : ''

    if (config.warnHandler) {
      config.warnHandler.call(null, msg, vm, trace)
    } else if (hasConsole && (!config.silent)) {
      console.error(`[Vue warn]: ${msg}${trace}`)
    }
  }
  • 分析?感覺自己水平有限,實際使用幾乎為零,沒啥分析的。有興趣看看這個文章,作者算是再Vue異常處理方面進行研究,這里

# ignoredElements

  • 源碼位置 core/dom/patch.js
  function isUnknownElement (vnode, inVPre) {
    return (
      !inVPre &&
      !vnode.ns &&
      !(
        config.ignoredElements.length &&
        config.ignoredElements.some(ignore => {
          return isRegExp(ignore)
            ? ignore.test(vnode.tag)
            : ignore === vnode.tag
        })
      ) &&
      config.isUnknownElement(vnode.tag)
    )
  }
  • 分析?官方文檔提供的很好,

須使 Vue 忽略在 Vue 之外的自定義元素 (e.g. 使用了 Web Components APIs)。否則,它會假設你忘記注冊全局組件或者拼錯了組件名稱,從而拋出一個關於 Unknown custom element 的警告。

代碼也很清晰。可以看到報錯點會出現在Vue進行數據驅動的核心方法creatElm中。


# keyCodes

  • 源碼位置 core/instance/render-helpers/check-keycodes.js
function isKeyNotMatch<T> (expect: T | Array<T>, actual: T): boolean {
  if (Array.isArray(expect)) {
    return expect.indexOf(actual) === -1
  } else {
    return expect !== actual
  }
}

/**
 * Runtime helper for checking keyCodes from config.
 * exposed as Vue.prototype._k
 * passing in eventKeyName as last argument separately for backwards compat
 */
export function checkKeyCodes (
  eventKeyCode: number,
  key: string,
  builtInKeyCode?: number | Array<number>,
  eventKeyName?: string,
  builtInKeyName?: string | Array<string>
): ?boolean {
  const mappedKeyCode = config.keyCodes[key] || builtInKeyCode
  if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
    return isKeyNotMatch(builtInKeyName, eventKeyName)
  } else if (mappedKeyCode) {
    return isKeyNotMatch(mappedKeyCode, eventKeyCode)
  } else if (eventKeyName) {
    return hyphenate(eventKeyName) !== key
  }
}
  • 分析: 這個玩意,我專門實踐了一下,其實就是自定義別名,看文檔我當時有點懵逼,我改成了 如下
Vue.config.keyCodes = {
  v: 86,
  // 取而代之的是 kebab-case 且用雙引號括起來
  "media-play-pause": 86,
}
<input type="text" @keyup.media-play-pause="method($event)">

這里,你就會發現他就是定義自己的別名去對應專屬的,keyCode個人感覺沒啥用,
實現的話,就是源碼方面的處理。隨后又走了proxy,完成代理。不多贅述


# prformance

直接飲用官方說明

用法:
設置為 true 以在瀏覽器開發工具的性能/時間線面板中啟用對組件初始化、編譯、渲染和打補丁的性能追蹤。只適用於開發模式和支持 performance.mark API 的瀏覽器上。

使用的話,需要安裝一個插件,我一直安裝不成功,不知道為啥,有一篇文章寫得很好這里,可以查看。


# productionTip

  • 源碼地址:platforms/web/runtime/index.js
...
 if (process.env.NODE_ENV !== 'production' &&
      process.env.NODE_ENV !== 'test' &&
      config.productionTip !== false &&
      typeof console !== 'undefined'
    ) {
      console[console.info ? 'info' : 'log'](
        `You are running Vue in development mode.\n` +
        `Make sure to turn on production mode when deploying for production.\n` +
        `See more tips at https://vuejs.org/guide/deployment.html`
      )
...

如官方說明

用法:
設置為 false 以阻止 vue 在啟動時生成生產提示。


  • 關於全局配置部分總結:
  1. 個人將全局配置部分算是淺顯的走了一遍,說實話,其中部分內容我幾乎都沒有用過,而且確實這個梳理,更多像是,CV一下文檔和源碼代碼。其中細節沒有去深究,
  2. 整個Vue api 梳理的想法就是讓我重新對Vue進行了解一下,畢竟Vue是個很大的項目,對於每個API不可能都去研究源碼的細節,但求,有個概念,實操有個印象,也算事我對Vue,進一步了解。
  3. 關於源碼部分,我也在同時學習,主要還是准備針對性的對他數據驅動和響應式的核心 處理部分進行學習了解,當然這個Api系列,也是在個人有精力同時研究有意義的情況下,回去深入了解的,如果精力不夠或是從未涉及,我會找相對應我覺得不錯的博客放出鏈接。
  4. 本文全是個人向內容,希望對看到的你,有所幫助,也是我對Vue學習的一個梳理吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM