Heim  >  Artikel  >  Web-Frontend  >  Vue.js-Quellcode durch Lernen bereitstellen und injizieren

Vue.js-Quellcode durch Lernen bereitstellen und injizieren

小云云
小云云Original
2018-02-24 14:25:581563Durchsuche

Bereitstellungs- und Injektionsoptionen in der 2.2.0+ Version von Vue.js hinzugefügt. Sie erscheinen paarweise und werden verwendet, um Daten von der übergeordneten Komponente weiterzugeben.

Speicherort des Quellcodes

Wie zuvor befindet sich die Initialisierungsmethode in der _init-Methode von Vue.

  // 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')
  }

Die Methoden initInjections und initProvide finden Sie hier. Dies ist die Initialisierungsmethode von provide und inject. Beide Methoden sind in src/core/instance/inject.js enthalten.

provide

provide-Option sollte ein Objekt oder eine Funktion sein, die ein Objekt zurückgibt. Dieses Objekt enthält Eigenschaften, die in seine Nachkommen eingefügt werden können. Sie können ES2015-Symbole als Schlüssel in diesem Objekt verwenden, dies funktioniert jedoch nur in Umgebungen, die Symbol und Reflect.ownKeys nativ unterstützen.

Schauen Sie sich zuerst den Quellcode an:

// 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
  }
}

stellen Sie die Option zur Datenweitergabe nach unten bereit. Hier erhalten wir zunächst den Inhalt in der Bereitstellungsoption. Wenn es eine Bereitstellungsoption gibt, übergeben Sie die Bereitstellungsoption an vm._provided, um zu den globalen Daten der Vue-Instanz zu werden.
Sehen Sie sich das Beispiel hier an, um es klarer zu machen. Im folgenden Beispiel werden die Daten foo übergeben und der Dateninhalt ist bar.

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

inject

inject option sollte ein String-Array oder ein Objekt sein, der Schlüssel des Objekts stellt den Namen der lokalen Bindung dar und der Wert ist sein Schlüssel ( Zeichenfolge oder Symbol), um nach verfügbaren Injektionen zu suchen.

Quellcode

// 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
  }
}

Sie können zunächst die Suchergebnisse der Injektionsoption über die Methode resolveInject abrufen die Suchergebnisse und fügen Sie sie zu Setter und Getter zu den Daten hinzufügen hinzu.
Dann schauen wir uns die resolveInject-Methode an:

export function resolveInject (inject: any, vm: Component): ?Object {
  if (inject) {    // inject 是 :any 类型因为流没有智能到能够指出缓存
    const result = Object.create(null)    // 获取 inject 选项的 key 数组
    const keys = hasSymbol
      ? Reflect.ownKeys(inject).filter(key => {        /* istanbul ignore next */
        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 (&#39;default&#39; in inject[key]) {          const provideDefault = inject[key].default
          result[key] = typeof provideDefault === &#39;function&#39;
            ? provideDefault.call(vm)
            : provideDefault
        } else if (process.env.NODE_ENV !== &#39;production&#39;) {
          warn(`Injection "${key}" not found`, vm)
        }
      }
    }    return result
  }
}

Rufen Sie das Schlüsselarray der Injektionsoption ab, durchlaufen Sie das Schlüsselarray und blasen Sie nach oben, um herauszufinden, ob ein Schlüssel in der Bereitstellung vorhanden ist den gleichen Namen wie das from-Attribut in der inject-Option. Wenn ja, übergeben Sie diese Daten an result. Wenn nicht, prüfen Sie, ob inject eine Standardoption zum Festlegen eines Standardwerts oder einer Standardmethode hat. Wenn ja, geben Sie den Standardwert an result zurück und schließlich das Ergebnisobjekt zurückgeben.
Inject sollte also mit einem Standardwert geschrieben werden:

const Child = {
  inject: {
    foo: { default: &#39;foo&#39; }
  }
}

oder mit einem From-Suchschlüssel und einem Standardwert:

const Child = {
  inject: {
    foo: {
      from: &#39;bar&#39;,      default: &#39;foo&#39;
    }
  }
}

oder mit einem Standardwert Die Einstellung ist eine Fabrikmethode:

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

Okay, ich gebe zu, dass dies die drei Beispiele sind, die auf der offiziellen Website zitiert wurden ~ Aber es ist einfach interessant.
Ich habe hier eine Frage. Da from und default im Quellcode aktiv identifiziert werden, heißt es auf der offiziellen Website, dass die Injektion von

in 2.5.0+ durch das Setzen des Defaults ermöglicht werden kann Wert. Optionen:

Ist die folgende Schreibmethode also noch verfügbar?

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

Aus diesem Grund schauen wir uns an, wie die 2.2.0-Version von Vue geschrieben ist?

export function initInjections (vm: Component) {
  const provide = vm.$options.provide  const inject: any = vm.$options.inject  if (provide) {
    vm._provided = typeof provide === &#39;function&#39;
      ? 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
      }
    }
  }
}

Wie Sie sehen können, werden in dieser Version Provide und Inject gemeinsam initialisiert. Danach wird „provide“ an vm._provide übergeben. Beim Abrufen der Option „inject“ bestimmt der Code, ob es sich bei „inject“ um ein Array handelt, und durchläuft dann das Array, um „provide“ zu finden .
Also spekuliere ich: Nach 2.5.0+ können Sie Array Form Inject nicht mehr verwenden, um nach Provide zu suchen.

Das obige ist der detaillierte Inhalt vonVue.js-Quellcode durch Lernen bereitstellen und injizieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn