Mehrere Vue-Instanzen auf derselben Seite mit derselben Codebasis

Lesezeit: 5 Minuten

Benutzer-Avatar
sMyles

Ich arbeite daran, die Funktionalität von Vue.js in das WordPress-Ökosystem zu bringen, und mein erstes Projekt betrifft das Suchen und Filtern auf einer Seite.

Da die Hauptwebsite anfänglich von WordPress mit PHP/HTML gerendert wird, lasse ich Vue auf der Seite initialisieren, die an ein HTML-Element angehängt wird, das ich mit WordPress ausgebe. Das funktioniert alles einwandfrei, aber jetzt versuche ich, noch einen Schritt weiter zu gehen, indem ich mehrere Instanzen derselben Codebasis habe (die zusammenarbeiten können).

Nehmen Sie diesen Beispiel-Screenshot von Indeed (nehmen Sie einfach an, dies ist eine WordPress-Site):
mehrere vue-Instanzen

Da die gesamte Ausgabe nicht in Vue.js erfolgt, muss ich mehrere HTML-DIV-Elemente von der WordPress-Seite ausgeben und Vue darauf initialisieren.

Da das Formular/die Felder basierend auf der Benutzerkonfiguration/-einrichtung dynamisch generiert werden, würde dieselbe Codebasis für beide Instanzen verwendet … aber ich muss es irgendwie schaffen, damit sie gemeinsam zusammenarbeiten können, um zu sagen, die Ergebnisse zu aktualisieren auf der Seite, wenn ein Wert ausgewählt oder geändert wird, in einem der Fälle.

Die Idee hier ist, in meiner Haupt-JS-Datei Vanille-Javascript zu verwenden, um alle meine spezifischen HTML-Elemente zu erkennen, die auf der Seite vorhanden sind (vielleicht sogar einen Slug für jedes einzelne in einem Datenobjekt zu definieren), und dann eine foreach-Schleife auszuführen, um dann a zu initieren new Vue() auf jeder Instanz.

Mein erster Gedanke ist, Vuex-Speicher zu verwenden, den einzelnen Speicher an alle Instanzen anzuhängen, alle ausgewählten Werte zu speichern und einen Versand auszulösen, um die Auflistungen zu aktualisieren, wenn sich einer von ihnen ändert.

Hat jemand etwas Ähnliches schon mal gemacht? Gibt es irgendetwas, worüber ich mich dabei ärgern sollte? Oder hat jemand einen besseren Vorschlag, wie man das machen sollte?

Ich dachte, es wäre besser für mich, hier nachzufragen, anstatt auf die harte Tour zu lernen und dann später herauszufinden, dass es möglicherweise nicht möglich ist oder dass es Probleme dabei geben wird.

Anregungen, Kommentare, Kritik oder Ideen sind sehr willkommen

aktualisieren
Hatte einen Vorschlag, die Vue-Instanz einfach an den Körper zu binden, entfernen Sie die render Funktion, und geben Sie dann einfach das Komponenten-HTML-Element aus, wo es benötigt wird (anstatt ein div auszugeben und dann daran anzuhängen). Ich werde das testen, bin aber neugierig auf Gedanken dazu?

  • Ein Eventbus ist hier das Richtige. Damit können Sie mehrere Vue-Instanzen (und ihre Komponenten darin) miteinander kommunizieren lassen. VueX kann die Arbeit auch erledigen, aber viele würden es für übertrieben halten, da dies kein SPA ist.

    – MarsAndBack

    22. September 2020 um 20:23 Uhr

Für alle, die darauf stoßen, habe ich die Vue-Instanzen einfach so initialisiert:

const sections = document.getElementsByClassName( "my-wrapper" )

for ( var i = 0; i < sections.length; i ++ ) {
    new Vue( {
         el: '#' + sections[ i ].id,
         store
     })
}

Grundsätzlich wird eine neue Vue-Instanz für jede auf der Seite gefundene Ausgabe initialisiert, wobei der gemeinsame Speicher an jede weitergegeben wird.

  • Wie gut hat das am Ende für Sie funktioniert? (vorausgesetzt, Ihr Projekt schreitet voran)

    – Robert

    2. November 2021 um 23:25 Uhr

  • @robert hat super funktioniert und es heute noch verwendet, Tausende von Installationen und keine wirklichen “großen” Probleme, die ich gefunden habe

    – Lächeln

    5. November 2021 um 17:55 Uhr

  • Vielen Dank. Gut zu hören! Ich habe mich in meiner Vue3+-Arbeit von Vuex wegbewegt, also denke ich über Nachrichten zwischen Instanzen nach (wie mkuehn hier: forum.vuejs.org/t/…)

    – Robert

    5. November 2021 um 21:24 Uhr

Ich habe diese Einrichtung mehrerer Vue-Instanzen nicht selbst durchgeführt, aber ich habe an einigen Stellen gelesen, dass Vue diesen Anwendungsfall unterstützen soll. Siehe zum Beispiel hier: Vue: Sind mehrere Vue-Apps für eine einzelne Website in Ordnung?

Vuex eignet sich hervorragend für eine größere SPA mit mehreren Komponenten, und was Sie vorschlagen, ist im Wesentlichen dasselbe, ohne eine gemeinsame Stamminstanz zwischen allen Komponenten. Hier wird der Vuex Store sehr nützlich sein, indem er jede Vue-Komponente auf der Seite mit einer einzigen „Quelle der Wahrheit“ der App-Daten synchronisiert hält.

Ich bin mir nicht sicher, ob ich diesen Teil Ihrer Frage verstehe:

Mein erster Gedanke ist, Vuex-Speicher zu verwenden, den einzelnen Speicher an alle Instanzen anzuhängen, alle ausgewählten Werte zu speichern und Auslösen eines Versands, um die Einträge zu aktualisieren, wenn sich einer von ihnen ändert.

Wenn die Daten im Vuex Store aktualisiert werden und Sie Vuex ordnungsgemäß einrichten, werden Aktualisierungen des DOM automatisch “reaktiv” durchgeführt. Es ist keine Aktion erforderlich, außer die Daten des Geschäfts zu ändern.

In Bezug auf Ihr Update funktioniert es vielleicht, aber es scheint mir keine gute Idee zu sein. Es hört sich so an, als würde es gegen die Art und Weise verstoßen, wie Vue normalerweise verwendet wird, und ich erinnere mich an keinen Teil der Dokumentation, der ein solches Setup erwähnt.

Wie ich schon sagte, ich habe keine direkte Erfahrung mit Ihrem vorgeschlagenen Design, daher habe ich möglicherweise etwas übersehen. Dachte ich teile trotzdem.

Um mehr instanze vue auszuführen, müssen Sie die Elemente, an die Sie vue anhängen (beachten Sie die Elemente el ), von folgendem Code trennen:

<div id="app" class="container">
        <my-component 
        v-for="(item,index) in array_2_element" 
        v-bind:item="item"
        v-bind:index="index"
        v-bind:key="item.name"
        > test componente <br> <my-component>
      </div>
      <hr><br>
  </div>
</div>

  <div id="todo-list-example">
    <form v-on:submit.prevent="addNewTodo">
      <label for="new-todo"> add a todo </label>
      <input type="text" 
      v-model="newTodoText"
      id="new-todo"
      placeholder="E.g. Feed to cat "
      >
      <button type="button" class="btn btn-primary"> add</button>
    </form>
    <ul>
      <li
      is="todo-item"
      v-for="(todo,index ) in todos "
      v-bind:key="todo.id"
      v-bind:title="todo.title"
      v-on:remove="todos.splice(index,1)"
      ></li>
    </ul>
  </div>

<script> 
    var vm2= new Vue({
    el: '#todo-list-example',
    // do somethings 
});

var vm = new Vue({
    el: '#app',
    // do somethings 
})
</script>

1373210cookie-checkMehrere Vue-Instanzen auf derselben Seite mit derselben Codebasis

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy