Suche…


Einführung

Vuex ist eine Zustandsverwaltungsstruktur + Bibliothek für Vue.js-Anwendungen. Es dient als zentraler Speicher für alle Komponenten in einer Anwendung. Regeln sorgen dafür, dass der Zustand nur in vorhersehbarer Weise mutiert werden kann. Es ist auch in die Erweiterung der offiziellen Entwicklertools von Vue integriert und bietet erweiterte Funktionen wie Null-Konfigurations-Debugging für Zeitreisen und Export / Import von Status-Snapshots.

Was ist Vuex?

Vuex ist ein offizielles Plugin für Vue.js, das einen zentralisierten Datastore zur Verwendung in Ihrer Anwendung bietet. Sie wird stark von der Flux-Anwendungsarchitektur beeinflusst, die einen unidirektionalen Datenfluss bietet, was zu einem einfacheren Anwendungsdesign und Argumentation führt.

In einer Vuex-Anwendung enthält der Datastore den gesamten Status der gemeinsam genutzten Anwendung . Dieser Zustand wird durch Mutationen geändert, die als Reaktion auf eine Aktion ausgeführt werden, die ein Mutationsereignis über den Dispatcher aufruft.

Ein Beispiel für den Datenfluss in einer Vuex-Anwendung ist in der folgenden Abbildung dargestellt. Vuex-Anwendungsarchitektur Diagramm, das unter der MIT- Lizenz verwendet wird, ursprünglich aus dem offiziellen Vuex GitHub-Repo .

Einzelne Vue.js-Anwendungskomponenten können auf das Speicherobjekt zugreifen, um Daten über Getter abzurufen, bei denen es sich um reine Funktionen handelt, die eine Nur-Lese-Kopie der gewünschten Daten zurückgeben.

Die Komponenten können Aktionen haben , die Funktionen sind , die Änderungen an der Komponente eigene Kopie der Daten durchführen, den Dispatcher verwenden , um ein Mutationsereignis zu versenden. Dieses Ereignis wird dann vom Datastore verarbeitet, der den Status bei Bedarf aktualisiert.

Änderungen werden dann automatisch in der gesamten Anwendung übernommen, da alle Komponenten über ihre Getter reaktiv an das Geschäft gebunden werden.


Ein Beispiel, das die Verwendung von Vuex in einem Vue-Projekt veranschaulicht.

const state = {
    lastClickTime: null
}

const mutations = {
    updateLastClickTime: (state, payload) => {
      state.lastClickTime = payload
  }
}

const getters = {
  getLastClickTime: state => {
    return new Date(state.lastClickTime)
  }
}

const actions = {
    syncUpdateTime: ({ commit }, payload) => {
    commit("updateLastClickTime", payload)
  },
  asyncUpdateTime: ({ commit }, payload) => {
    setTimeout(() => {
      commit("updateLastClickTime", payload)
    }, Math.random() * 5000)
  }
}

const store = new Vuex.Store({
  state,
  getters,
  mutations,
  actions
})

const { mapActions, mapGetters } = Vuex;

// Vue 
const vm = new Vue({
    el: '#container',
  store,
  computed: {
      ...mapGetters([
        'getLastClickTime'
    ])
  },
  methods: {
      ...mapActions([
        'syncUpdateTime',
      'asyncUpdateTime'
    ]),
    updateTimeSyncTest () {
        this.syncUpdateTime(Date.now())
    },
    updateTimeAsyncTest () {
        this.asyncUpdateTime(Date.now())
    }
  }
})

Und die HTML-Vorlage für das gleiche:

<div id="container">
  <p>{{ getLastClickTime || "No time selected yet" }}</p>
  <button @click="updateTimeSyncTest">Sync Action test</button>
  <button @click="updateTimeAsyncTest">Async Action test</button>
</div>
  1. Hier enthält der Zustand die lastClickTime- Eigenschaft, die als null initialisiert wurde. Diese Einrichtung von Standardwerten ist wichtig , die Eigenschaften reaktiv zu halten. Eigenschaften, die im Zustand nicht erwähnt werden, sind verfügbar, aber die danach vorgenommenen Änderungen sind nicht mit Hilfe von Gettern zugänglich .

  2. Der verwendete Getter stellt eine berechnete Eigenschaft bereit, die jedes Mal aktualisiert wird, wenn eine Mutation den Wert der Eigenschaft state aktualisiert.

  3. Nur Mutationen dürfen den Zustand und seine Eigenschaften ändern, das heißt, dies geschieht nur synchron .

  4. Eine Aktion kann für asynchrone Aktualisierungen verwendet werden, bei denen der API-Aufruf (der hier durch den zufallsgesteuerten setTimeout verspottet wird) in der Aktion ausgeführt werden kann, und nachdem die Antwort abgerufen wurde, eine Mutation ausgeführt werden kann, um die Änderung des Status vorzunehmen .

Warum Vuex verwenden?

Wenn Sie große Anwendungen wie Single-Page-Apps (SPAs) erstellen, die in der Regel aus vielen wiederverwendbaren Komponenten bestehen, können sie sehr schwer zu erstellen und zu warten sein. Die gemeinsame Nutzung von Daten und Zuständen zwischen diesen Komponenten kann auch schnell brechen und das Debugging und die Wartung schwierig werden.

Durch die Verwendung eines zentralen Anwendungsdatenspeichers kann der gesamte Anwendungsstatus an einer Stelle dargestellt werden, wodurch die Anwendung organisierter wird. Durch die Verwendung eines unidirektionalen Datenflusses, durch Mutationen und durch das Festlegen des Zugriffs auf Komponentendaten auf die erforderlichen Daten wird es viel einfacher, die Komponentenrolle und die Auswirkungen auf den Anwendungsstatus zu beurteilen.

VueJS-Komponenten sind separate Entitäten und können Daten nicht einfach untereinander austauschen. Um Daten ohne Vuex gemeinsam zu nutzen, müssen wir ein Ereignis mit Daten emit und dann das Ereignis mit on überwachen.

Komponente 1

this.$emit('eventWithDataObject', dataObject)

Komponente 2

this.$on('eventWithDataObject', function (dataObject) {
    console.log(dataObject)
})

Wenn vuex installiert ist, können wir einfach von jeder Komponente aus auf die Daten zugreifen, ohne dass Ereignisse abgehört werden müssen.

this.$store.state.myData

Wir können Daten auch synchron mit Mutatoren ändern , asynchrone Aktionen verwenden und Daten mit Getter- Funktionen abrufen .

Getterfunktionen funktionieren möglicherweise als global berechnete Funktionen. Wir können auf sie von Komponenten zugreifen:

this.$store.getters.myGetter

Aktionen sind globale Methoden. Wir können sie aus Komponenten versenden:

this.$store.dispatch('myAction', myDataObject)

Mutationen sind die einzige Möglichkeit, Daten in vuex zu ändern. Wir können Änderungen festschreiben:

this.$store.commit('myMutation', myDataObject)

Vuex-Code würde so aussehen

state: {
  myData: {
    key: 'val'
  }
},
getters: {
  myGetter: state => {
     return state.myData.key.length
  }
},
actions: {
  myAction ({ commit }, myDataObject) {
    setTimeout(() => {
      commit('myMutation', myDataObject)
    }, 2000)
  }
},
mutations: {
  myMutation (state, myDataObject) {
    state.myData = myDataObject
  }
}

Wie installiere ich Vuex?

In den meisten Fällen verwenden Sie Vuex in größeren komponentenbasierten Anwendungen, in denen Sie wahrscheinlich einen Modul-Bundler wie Webpack oder Browserify in Verbindung mit Vueify verwenden, wenn Sie einzelne Dateien verwenden.

In diesem Fall ist der einfachste Weg, um Vuex zu erhalten, über NPM. Führen Sie den folgenden Befehl aus, um Vuex zu installieren, und speichern Sie es in Ihren Anwendungsabhängigkeiten.

 npm install --save vuex

Stellen Sie sicher, dass Sie Vuex mit Ihrem Vue-Setup verknüpfen, indem Sie die folgende Zeile nach der Anweisung von Request require('vue') einfügen.

Vue.use(require('vuex'))

Vuex ist auch als CDN erhältlich. Sie können die neueste Version von cdnjs hier herunterladen.

Automatisch unzulässige Benachrichtigungen

In diesem Beispiel wird ein Vuex-Modul dynamisch registriert, um benutzerdefinierte Benachrichtigungen zu speichern, die automatisch verworfen werden können

notifications.js

vuex store auflösen und einige Konstanten definieren

//Vuex store previously configured on other side
import _store from 'path/to/store';

//Notification default duration in milliseconds
const defaultDuration = 8000;

//Valid mutation names
const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED';
const NOTIFICATION_DISMISSED = 'NOTIFICATION_DISMISSED';

Setzen Sie unser Modul in den Ausgangszustand

const state = {
  Notifications: []
}

Setze unsere Modul-Getter

const getters = {
  //All notifications, we are returning only the raw notification objects
  Notifications: state => state.Notifications.map(n => n.Raw)
}

Setzen Sie unser Modul Aktionen

const actions = {
  //On actions we receive a context object which exposes the 
  //same set of methods/properties on the store instance
  //{commit} is a shorthand for context.commit, this is an 
  //ES2015 feature called argument destructuring
  Add({ commit }, notification) {
    //Get notification duration or use default duration
    let duration = notification.duration || defaultDuration

    //Create a timeout to dismiss notification
    var timeOut = setTimeout(function () {
      //On timeout mutate state to dismiss notification
      commit(NOTIFICATION_DISMISSED, notification);
    }, duration);

    //Mutate state to add new notification, we create a new object 
    //for save original raw notification object and timeout reference
    commit(NOTIFICATION_ADDED, {
      Raw: notification,
      TimeOut: timeOut
    })
  },
  //Here we are using context object directly
  Dismiss(context, notification) {
    //Just pass payload
    context.commit(NOTIFICATION_DISMISSED, notification);
  }
}

Setze unsere Modulmutationen

const mutations = {
  //On mutations we receive current state and a payload
  [NOTIFICATION_ADDED](state, notification) {
    state.Notifications.push(notification);
  },
  //remember, current state and payload
  [NOTIFICATION_DISMISSED](state, rawNotification) {
    var i = state.Notifications.map(n => n.Raw).indexOf(rawNotification);
    if (i == -1) {
      return;
    }

    clearTimeout(state.Notifications[i].TimeOut);
    state.Notifications.splice(i, 1);
  }
}

Registrieren Sie unser Modul mit definiertem Zustand, Eingaben, Aktionen und Mutationen

_store.registerModule('notifications', {
  state,
  getters,
  actions,
  mutations
});

Verwendungszweck

componentA.vue

Diese Komponente zeigt alle Benachrichtigungen als Warnmeldungen des Bootstraps in der oberen rechten Ecke des Bildschirms an. Außerdem können Sie jede Benachrichtigung manuell abbrechen.

<template>
<transition-group name="notification-list" tag="div" class="top-right">
  <div v-for="alert in alerts" v-bind:key="alert" class="notification alert alert-dismissible" v-bind:class="'alert-'+alert.type">
    <button v-on:click="dismiss(alert)" type="button" class="close" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <div>
      <div>
        <strong>{{alert.title}}</strong>
      </div>
      <div>
        {{alert.text}}
      </div>
    </div>
  </div>
</transition-group>
</template>

<script>
export default {
  name: 'arc-notifications',
  computed: {
    alerts() {
      //Get all notifications from store
      return this.$store.getters.Notifications;
    }
  },
  methods: {
    //Manually dismiss a notification
    dismiss(alert) {
      this.$store.dispatch('Dismiss', alert);
    }
  }
}
</script>
<style lang="scss" scoped>
$margin: 15px;

.top-right {
    top: $margin;
    right: $margin;
    left: auto;
    width: 300px;
    //height: 600px;
    position: absolute;
    opacity: 0.95;
    z-index: 100;
    display: flex;
    flex-wrap: wrap;
    //background-color: red;
}
.notification {
    transition: all 0.8s;
    display: flex;
    width: 100%;
    position: relative;
    margin-bottom: 10px;
    .close {
        position: absolute;
        right: 10px;
        top: 5px;
    }

    > div {
        position: relative;
        display: inline;
    }
}
.notification:last-child {
    margin-bottom: 0;
}
.notification-list-enter,
.notification-list-leave-active {
    opacity: 0;
    transform: translateX(-90px);
}
.notification-list-leave-active {
    position: absolute;
}
</style>

Snippet zum Hinzufügen einer Benachrichtigung in einer anderen Komponente

//payload could be anything, this example content matches with componentA.vue 
this.$store.dispatch('Add', {
  title = 'Hello',
  text = 'World',
  type = 'info',
  duration = 15000
});


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow