2017-01-19 4 views
1

Ich möchte einige Eigenschaften von einem übergeordneten Element an alle untergeordneten Elemente übergeben, wenn diese übertragen werden (Inhaltsverteilungssyntax). In diesem Fall weiß der Elternteil (soweit ich weiß) seine Kinder nicht, also weiß ich nicht weiter.Übergeben Sie die Eigenschaften von der übergeordneten Komponente an alle übergelagerten untergeordneten Komponenten in Vue

Mehr specificly, möchte ich eine Möglichkeit, dies zu schreiben:

<my-parent prop1="foo" prop2="bar"> 
    <my-children></my-children> <!-- Must know content of prop1 and prop2 --> 
    <my-children></my-children> <!-- Must know content of prop1 and prop2 --> 
</my-parent> 

Anstatt diese schreiben aufweist:

<my-parent prop1="foo" prop2="bar"> 
    <my-children prop1="foo" prop2="bar"></my-children> 
    <my-children prop1="foo" prop2="bar"></my-children> 
</my-parent> 

Ist es möglich? Vielen Dank.

+0

Hatten Sie vuex in Betracht ziehen? – AldoRomo88

+1

@ AldoRomo88 Bitte nein, ich möchte nur ein dummes Argument an alle Kinder weitergeben, nicht um einen vollen Redux-Zustand zu verwalten. Das gilt auch für wiederverwendbare Komponenten. Je weniger Abhängigkeiten es hat, desto besser wird es. – Cobaltway

Antwort

1

Hier ist meine Lösung hilft, das ist wahrscheinlich nicht sehr viel, aber das ist die sauberste Lösung für das, was ich jetzt tun soll. Das Prinzip besteht darin, berechnete Eigenschaften zu erstellen, die eine eigene Komponentenreferenz verwenden, falls sie vorhanden sind, oder andernfalls $ parent-Werte zu erhalten. Die reale Requisite wäre dann in this._prop zugänglich. Hier

Vue.component('my-children', { 
    props: ["prop1", "prop2"], 
    template: "<div>{{_prop1}} - {{_prop2}}</div>", 
    computed: { 
     _prop1: function() { 
      return this.prop1 || this.$parent.prop1; 
     }, 
     _prop2: function() { 
      return this.prop2 || this.$parent.prop2; 
     } 
    } 
}); 

ist ein mixin Generator, der das tut in eine elegantere Art und Weise und mit möglicherweise mehreren Ebenen:

function passDown(...passDownProperties) { 
    const computed = {}; 
    passDownProperties.forEach((prop) => { 
     computed["_" + prop] = function() { 
      return this[prop] || this.$parent[prop] || this.$parent["_" + prop]; 
     }; 
    }); 
    return { computed }; 
} 

Vue.component('my-children', { 
    props: ["prop1", "prop2"], 
    template: "<div>{{_prop1}} - {{_prop2}}</div>", 
    mixins: [passDown("prop1", "prop2")] 
}); 
+0

Ich mag es !, Ihre Lösung ist sauberer als meine und funktioniert sehr gut – AldoRomo88

0

Requisiten ermöglichen Datenfluss nur eine Ebene. Wenn Sie Daten verewigen möchten, können Sie stattdessen einen Ereignisbus verwenden.

Instanziieren Sie einen Ereignisbus mit einer leeren Vue-Instanz in Ihrer Hauptdatei.

var bus = new Vue(); 

Dann in Ihren Eltern, emittieren die Veranstaltung mit Daten Anhören

bus.$emit('myEvent', dataToBePassed); 

für Sie myEvent überall wollen die Daten abholen weitergegeben werden. In Ihrem Fall ist es in Ihrem Kind Komponenten getan

bus.$on('myEvent', function(data) { 
    ..... 
}); 
1

An dieser Stelle (ich bin kein Experte vue) Ich habe gerade in dieser Lösung einfiel.

Weisen Sie jeder Komponente Requisiten ist langweilig Ich stimme zu, also warum es nicht programmgesteuert tun?

// Create a global mixin 
Vue.mixin({ 
    mounted() { // each component will execute this function after mounted 
    if (!this.$children) { 
     return; 
    } 

    for (const child of this.$children) { // iterate each child component 
     if (child.$options._propKeys) { 
     for (const propKey of child.$options._propKeys) { // iterate each child's props 
      // if current component has a property named equal to child prop key 
      if (Object.prototype.hasOwnProperty.call(this, propKey)) { 
      // update child prop value 
      this.$set(child, propKey, this[propKey]); 

      // create a watch to update value again every time that parent property changes 
      this.$watch(propKey, (newValue) => { 
       this.$set(child, propKey, newValue); 
      }); 
      } 
     } 
     } 
    } 
    }, 
}); 

Dies funktioniert, aber Sie werden eine hässliche vue warnen Meldung:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. 

Ich bin nicht sicher, ob dies eine gute Lösung ist, aber es funktioniert, also, wenn Sie sich entscheiden, nur zu verwenden, in halten Global-Mixin recomendations dagegen:

Verwenden globalen Mixins dünn und vorsichtig, weil es jedes einzelne Vue-Instanz erstellt, einschließlich der Komponenten von Drittanbietern beeinflusst.

finden Sie ein vollständiges Beispiel bei https://github.com/aldoromo88/PropsConvention

Hoffe, dass es

+0

Vielen Dank für Ihre Antwort: Ich komme in etwas, das so aussah, aber die Warnung und die Notwendigkeit, jede Requisite explizit zu beobachten, waren ein wenig abstoßend für mich. Ich werde auch meine eigene Lösung basierend auf dem inversen Ansatz einreichen. – Cobaltway

Verwandte Themen