久久久久在线观看_又色又爽又黄的免费视频播放_一区中文字幕_日韩电影在线播放

今日焦點(diǎn) 焦點(diǎn)資訊 營(yíng)銷(xiāo)之道 企業(yè)報(bào)道 淘寶運(yùn)營(yíng) 網(wǎng)站建設(shè) 軟件開(kāi)發(fā) 400電話
  當(dāng)前位置: 首頁(yè) » 資訊 » 軟件開(kāi)發(fā) » 正文

Vue.js源碼學(xué)習(xí)provide 和 inject

放大字體  縮小字體 發(fā)布日期:2018-02-24  來(lái)源:企業(yè)800網(wǎng)  作者:新格網(wǎng)  瀏覽次數(shù):344  【去百度看看】
核心提示:在 Vue.js 的 2.2.0+ 版本中添加加了 provide 和 inject 選項(xiàng)。他們成對(duì)出現(xiàn),用于父級(jí)組件向下傳遞數(shù)據(jù)。
在 Vue.js 的 2.2.0+ 版本中添加加了 provide 和 inject 選項(xiàng)。他們成對(duì)出現(xiàn),用于父級(jí)組件向下傳遞數(shù)據(jù)。

源碼位置

和之前一樣,初始化的方法都是在 Vue 的 _init 方法中的。

  // src/core/instance/init.js
  Vue.prototype._init = function (options?: Object) {
    ……
    vm._self = vm
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
  }

這里找到 initInjectionsinitProvide 方法,這就是 provideinject 的初始化方法了。這兩個(gè)方法都是在 src/core/instance/inject.js 中。

provide

provide 選項(xiàng)應(yīng)該是一個(gè)對(duì)象或返回一個(gè)對(duì)象的函數(shù)。該對(duì)象包含可注入其子孫的屬性。在該對(duì)象中你可以使用 ES2015 Symbols 作為 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的環(huán)境下可工作。

先看源碼:

// src/core/instance/inject.jsexport function initProvide (vm: Component) {
  const provide = vm.$options.provide  if (provide) {
    vm._provided = typeof provide === 'function'
      ? provide.call(vm)
      : provide
  }
}

provide 是向下傳遞數(shù)據(jù)的選項(xiàng)。這里先拿到 provide 選項(xiàng)中的內(nèi)容,如果有 provide 選項(xiàng),將 provide 選項(xiàng)傳遞給 vm._provided 變?yōu)?Vue 實(shí)例全局?jǐn)?shù)據(jù)。
這里看一下例子更清楚,下例中傳入數(shù)據(jù) foo,數(shù)據(jù)內(nèi)容為 bar

var Provider = {
  provide: {
    foo: 'bar'
  },  // ...}

inject

inject 選項(xiàng)應(yīng)該是一個(gè)字符串?dāng)?shù)組或一個(gè)對(duì)象,該對(duì)象的 key 代表了本地綁定的名稱(chēng),value 為其 key (字符串或 Symbol) 以在可用的注入中搜索。

源碼

// src/core/instance/inject.jsexport function initInjections (vm: Component) {
  const result = resolveInject(vm.$options.inject, vm)  if (result) {
    observerState.shouldConvert = false
    Object.keys(result).forEach(key => {
      defineReactive(vm, key, result[key])
    })
    observerState.shouldConvert = true
  }
}

簡(jiǎn)化后的源碼可以看到,首先通過(guò) resolveInject 方法獲取 inject 選項(xiàng)搜索結(jié)果,如果有搜索結(jié)果,遍歷搜索結(jié)果并為其中的數(shù)據(jù)添加 setter 和 getter。
接著來(lái)看下 resolveInject 方法:

export function resolveInject (inject: any, vm: Component): ?Object {
  if (inject) {    // inject 是 :any 類(lèi)型因?yàn)榱鳑](méi)有智能到能夠指出緩存
    const result = Object.create(null)    // 獲取 inject 選項(xiàng)的 key 數(shù)組
    const keys = hasSymbol
      ? Reflect.ownKeys(inject).filter(key => {        
        return Object.getOwnPropertyDescriptor(inject, key).enumerable
      })
      : Object.keys(inject)    for (let i = 0; i < keys.length; i++) {      const key = keys[i]      const provideKey = inject[key].from      let source = vm      while (source) {        if (source._provided && provideKey in source._provided) {
          result[key] = source._provided[provideKey]          break
        }
        source = source.$parent
      }      if (!source) {        if ('default' in inject[key]) {          const provideDefault = inject[key].default
          result[key] = typeof provideDefault === 'function'
            ? provideDefault.call(vm)
            : provideDefault
        } else if (process.env.NODE_ENV !== 'production') {
          warn(`Injection "${key}" not found`, vm)
        }
      }
    }    return result
  }
}

獲取 inject 選項(xiàng)的 key 數(shù)組,遍歷 key 數(shù)組,通過(guò)向上冒泡來(lái)查找 provide 中是否有 key 與 inject 選項(xiàng)中 from 屬性同名的,如果有,則將這個(gè)數(shù)據(jù)傳遞給 result;如果沒(méi)有,檢查 inject 是否有 default 選項(xiàng)設(shè)定默認(rèn)值或者默認(rèn)方法,如果有則將默認(rèn)值返傳給 result,最終返回 result 對(duì)象。
所以,inject 的寫(xiě)法應(yīng)該是有 default 默認(rèn)值的:

const Child = {
  inject: {
    foo: { default: 'foo' }
  }
}

或者是有 from 查找鍵和 default 默認(rèn)值的:

const Child = {
  inject: {
    foo: {
      from: 'bar',      default: 'foo'
    }
  }
}

或者為 default 默認(rèn)值設(shè)定一個(gè)工廠方法:

const Child = {
  inject: {
    foo: {
      from: 'bar',      default: () => [1, 2, 3]
    }
  }
}

好吧,我承認(rèn)這就是引用的官網(wǎng)的三個(gè)例子~ 不過(guò)意思到就好啦。
這里我有個(gè)疑問(wèn),既然在源碼中主動(dòng)去識(shí)別了 from 和 default,官網(wǎng)上說(shuō)是

2.5.0+ 的注入可以通過(guò)設(shè)置默認(rèn)值使其變成可選項(xiàng):

那么如下寫(xiě)法還可用嗎?

var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }  // ...}

為此,我們?nèi)ゲ椴?2.2.0 版本的Vue是怎么寫(xiě)的?

export function initInjections (vm: Component) {
  const provide = vm.$options.provide  const inject: any = vm.$options.inject  if (provide) {
    vm._provided = typeof provide === 'function'
      ? provide.call(vm)
      : provide
  }  if (inject) {    // inject is :any because flow is not smart enough to figure out cached
    // isArray here
    const isArray = Array.isArray(inject)    const keys = isArray
      ? inject
      : hasSymbol
        ? Reflect.ownKeys(inject)
        : Object.keys(inject)    for (let i = 0; i < keys.length; i++) {      const key = keys[i]      const provideKey = isArray ? key : inject[key]      let source = vm      while (source) {        if (source._provided && source._provided[provideKey]) {
          vm[key] = source._provided[provideKey]          break
        }
        source = source.$parent
      }
    }
  }
}

從中可以看到,在這個(gè)版本 provide 和 inject 是一起初始化的。之后,將 provide 傳給 vm._provide ,在獲取 inject 選項(xiàng)的時(shí)候代碼判斷了 inject 是否為數(shù)組,如果是數(shù)組直接遍歷數(shù)組,之后查找 provide 的代碼差不多。
所以我推測(cè): 2.5.0+ 之后不能再使用數(shù)組形式的 inject 來(lái)搜索 provide 了。

以上就是Vue.js源碼學(xué)習(xí)provide 和 inject的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

 
關(guān)鍵詞: javascript,provide,Vue.js?5.1.10
長(zhǎng)春  短信群發(fā)  吉林省  紅視窗  中國(guó)  長(zhǎng)春市  玉米  長(zhǎng)春網(wǎng)站建設(shè)  網(wǎng)站  振華  設(shè)備  設(shè)計(jì)  吉林  廣州  撲克  聯(lián)合聲明  敘利亞  美國(guó)  美國(guó)白宮  指示  塞內(nèi)加爾  新聞中心  化學(xué)武器  記者會(huì)  內(nèi)蒙古  白宮  化武  長(zhǎng)春上門(mén)維修電腦  消費(fèi)者權(quán)益  北京市  中消協(xié)  日本  強(qiáng)臺(tái)風(fēng)  非洲  中國(guó)政府  圓桌  滿(mǎn)洲里  敘政府  國(guó)家元首  毒品  小雨  臺(tái)風(fēng)  消費(fèi)者  海外網(wǎng)  中非  中非合作論壇  經(jīng)濟(jì)  大阪  突擊步槍  重慶市  俄羅斯  步槍  網(wǎng)站建設(shè)  長(zhǎng)春上門(mén)做系統(tǒng)  長(zhǎng)春電腦上門(mén)維修  黨委書(shū)記  北斗導(dǎo)航  長(zhǎng)春北大青鳥(niǎo)  售前咨詢(xún)技巧  長(zhǎng)春上門(mén)修電腦  政治  黨委  龍頭企業(yè)  位置服務(wù)  中國(guó)電影  中國(guó)智能建筑節(jié)  軍民  產(chǎn)業(yè)園  制造  侯建國(guó),質(zhì)量,中國(guó)特色社會(huì)主義  中國(guó)芯  特朗普  f-35  長(zhǎng)春國(guó)貿(mào)  AJAX  PHP  中國(guó)移動(dòng)  特朗普,貿(mào)易戰(zhàn),美國(guó)  XML  政府  州長(zhǎng)  RSS  美國(guó)人  一帶一路  中國(guó)軍網(wǎng)  發(fā)言人  塞申斯  小米  今日頭條  微博  發(fā)布會(huì)  彈道導(dǎo)彈  戰(zhàn)斗機(jī)  銀河  檢察官  中國(guó)市場(chǎng)  英國(guó)皇家海軍  運(yùn)載火箭  航母  戰(zhàn)機(jī) 
 
[ 資訊搜索 ]  [ 加入收藏 ]  [ 告訴好友 ]  [ 打印本文 ]  [ 違規(guī)舉報(bào) ]  [ 關(guān)閉窗口 ]

 
0條 [查看全部]  相關(guān)評(píng)論

 
網(wǎng)站首頁(yè) | 關(guān)于我們 | 聯(lián)系方式 | 使用協(xié)議 | 版權(quán)隱私 | 網(wǎng)站地圖 | 排名推廣 | 廣告服務(wù) | 積分換禮 | 網(wǎng)站留言 | RSS訂閱 | 吉ICP備19006030號(hào)-4
企業(yè)800網(wǎng) · 提供技術(shù)支持