Wie man bedingte Anweisungen zu v-for-Schleifen in Vue.js hinzufügt

Während ich kürzlich an einem großen Projekt in Vue.js gearbeitet habe, bin ich mehrmals auf ein Problem gestoßen, das häufig zu sein scheint, und dennoch konnte ich in der Dokumentation zu Vue.js keine Erklärung finden, wie ich damit umgehen soll.

Das Problem, auf das ich mich beziehe, besteht darin, unseren v-for-Schleifen in Vue bedingte Anweisungen hinzuzufügen.

Erlauben Sie mir, es mit einem Beispiel zu veranschaulichen:

Angenommen, wir möchten alle aktiven Benutzer auf einer Seite anzeigen. Wir haben bereits ein Datenobjekt in unserer Vue-Instanz, das alle Benutzerobjekte enthält. In jedem Benutzerobjekt gibt es ein Boolesches Feld, das angibt, ob ein Benutzer aktiv oder inaktiv ist (true bedeutet, dass er aktiv ist).

Nun das Problem:

Wir wollen dieses Users-Objekt mit der v-for-Direktive durchlaufen. Bei jeder Schleifeniteration zeigen wir einen anderen Benutzer an. Wir möchten jedoch nur aktive Benutzer durchlaufen. Wenn ein Benutzer inaktiv ist, möchten wir diese grundsätzlich überspringen.

Wie Sie sich vorstellen können, ist dies ein häufiges Szenario, bei dem Sie Objekte in einer bedingten Schleife durchlaufen möchten. Die Schleife nur für Objekte ausführen, die einem bestimmten Kriterium entsprechen. Die Frage ist, wie machst du das?

Mein natürlicher Instinkt

Natürlich habe ich darüber nachgedacht, ein v-for und ein v-if in einer Zeile zu kombinieren. Bei jeder Iteration überprüfe ich, ob sie einem bestimmten Kriterium entspricht. So was:

 

{{user.name}}

Ok, der obige Code könnte dein erster Instinkt sein, wie er für mich war. Beim Einrichten der Schleife fügen wir ein v-if hinzu, um zu entscheiden, ob die aktuelle Benutzeriteration ein aktiver Benutzer ist. Spoiler-Alarm: Dies funktioniert NICHT. Um auf den aktuellen Benutzer zugreifen zu können, müssen Sie das v-if an ein untergeordnetes Element des Elements anhängen, an das das v-forattached angehängt ist.

Anti-Patterns

Hierfür gibt es Umgehungsmöglichkeiten, die Sie ausprobieren können. In diesem einfachen Beispiel könnten wir das v-if an das

-Element anhängen. Es würde funktionieren, aber dies ist ein einfaches Beispiel und in der Praxis werden Sie viele Elemente haben, die Sie während jeder Schleifeniteration erstellen, so dass es nicht praktisch ist, jedem ein v-if hinzuzufügen.

Ich hatte auch die Idee, einen leeren Wrapper

zwischen dem Anfangselement der Schleife und den anderen Elementen zu erstellen. So was:

   
       

{{user.name}}     

Auch dies würde technisch funktionieren. Aber wir haben jetzt leere div-Elemente um jedes Objekt, die wahrscheinlich das DOM-Traversal- und Phantom-CSS-Styling stören können. Außerdem macht es unsere App unübersichtlich und fügt unserem HTML-Markup eine unnötige Struktur hinzu.

Ich sollte auch erwähnen, dass Sie immer noch inaktive Benutzer durchlaufen und eine Bedingung ausführen, bevor Sie die nächste Schleifeniteration unterbrechen und fortfahren. Dies könnte das Problem visuell lösen, aber Sie durchlaufen rechnerisch immer noch jeden einzelnen Benutzer in Ihrem System, anstatt nur die aktiven. Abhängig von der Größe Ihrer Nutzlast kann dies zu Leistungsproblemen führen.

Es muss einen besseren Weg geben ...

Die Lösung: Verwenden Sie berechnete Eigenschaften!

Ja, Sie wissen bereits über berechnete Eigenschaften Bescheid, aber wenn Sie nicht alle Benutzerobjekte durchlaufen und dann während der Schleife prüfen, ob sie unseren Kriterien entsprechen, können Sie einfach eine Teilmenge unserer Benutzer erstellen, die nur die aktiven Benutzer und darstellt Schleife nur diese Teilmenge!

Du kannst und du solltest. Berechnete Eigenschaften sind sehr performant.

Wenn Sie ein Array filtern:

Die einfache Lösung besteht darin, `.filter ()` zu verwenden, um nur die aktiven Benutzer zurückzugeben.

 

{{user.name}}

var app = new Vue ({
   el: "#app",
   Daten: {
     Benutzer: [
       {name: ‘Alex’, active: true},
       {name: ‘John’, active: false},
       {name: ‘James’, active: true}
     ]
   },
   berechnet: {
     activeUsers: function () {
       return this.users.filter (function (u) {
         return u.active
     })
   } // enthält nur Alex und James
 }
});

Lassen Sie uns ganz schnell sehen, was passiert. Schauen wir uns zuerst die Vue-Instanz an, die wir am unteren Rand des Dokuments erstellen. Es ist eine normale Vue-Instanz und Sie können unsere Daten sehen: Objekt enthält 3 Benutzer in Form eines Arrays (Dies ist wichtig, dass es sich um ein Array und nicht um ein Objekt handelt, dazu später mehr).

Jetzt haben wir in unserem Abschnitt mit berechneten Eigenschaften eine Eigenschaft activeUsers erstellt, die aus der Eigenschaft users im obigen Abschnitt data: {} berechnet wird.

Um alle aktiven Benutzer zu erhalten, verwenden wir einfach die Methode .filter () in unserem Array Users [] und behalten dann nur die Benutzer bei, bei denen .active wahr ist.

Weitere Informationen zu .filter () finden Sie in den Mozilla-Dokumenten.

Konzentrieren wir uns nun wieder auf die ursprüngliche Schleife am oberen Rand des Dokuments, die Sie sehen, und durchlaufen das activeUsers-Objekt anstelle des user-Objekts. Auf diese Weise wird garantiert, dass jede Schleifeniteration unsere Kriterien für die Schleife erfüllt. Wir brauchen dort keine zusätzlichen v-if-Anweisungen.

Ein Objekt filtern

Das obige Beispiel zeigt nun, wie Sie durch ein Array von Objekten filtern. Wenn Ihr Index / Schlüssel eine Ganzzahl ist, können Sie die obige Methode verwenden.

Diese Technik funktioniert jedoch nicht, da .filter () nur für Arrays (oder Objekte mit ganzzahligen Schlüsseln) gilt. Es funktioniert jedoch nicht, wenn Ihr Users {} -Objekt ungefähr so ​​aussieht:

{
  Alex: {active: true}
  John: {active: false},
  James: {active: true}
}

Denken Sie auch hier daran, dass dies zum Beispiel vereinfacht ist. Wenn Sie jedoch keine Ganzzahlschlüssel und stattdessen Zeichenfolgen-basierte Objektschlüssel haben, können Sie .filter () nicht verwenden. Das Konzept, berechnete Eigenschaften zum Filtern der Liste und anschließenden Schleifen der Computereigenschaft zu verwenden, gilt jedoch weiterhin.

Ich benutze Lodash sehr gerne und tendiere sowieso dazu, es für die meisten Projekte einzusetzen. Es gibt also eine großartige Möglichkeit, dies mit Lodash zu tun. Wir werden die _.pickBy () -Methode verwenden, um in jedes Objekt zu graben und nur diejenigen zurückzugeben, die unseren Kriterien entsprechen.

 

{{user.name}}

var app = new Vue ({
  el: "#app",
  Daten: {
    Benutzer: [
      {name: ‘Alex’, active: true},
      {name: ‘John’, active: false},
      {name: ‘James’, active: true}
    ]
  },
  berechnet: {
    activeUsers: function () {
      return _.pickBy (this.users, function (u) {
        return u.active;
      });
    } // enthält nur {Alex: {…}, James: {…}}
  }
});

Dies ist das gleiche Beispiel wie oben, aber Sie werden sehen, dass wir die Lodash _.pickBy () -Methode verwenden, um tiefer in jedes Objekt einzutauchen und eine Eigenschaft zu finden und dann den Benutzer als Teil unserer Gruppe zu akzeptieren, um es durchzuarbeiten.

Fazit

So haben Sie es, eine einfache Möglichkeit, Teilmengen größerer Objekte zu filtern oder bedingt zu durchlaufen! Am wichtigsten ist, dass es einfach zu pflegen ist und die Logik von HTML und dem Vue-Objekt (wo es hingehört) fernhält.