2017-01-08 1 views
7

Ich arbeite mit Vuex (2.1.1) und Dinge in Vue einzelne Dateikomponenten arbeiten. Um jedoch zu viel zu vermeiden, habe ich einige Funktionen in ein utils.js Modul verschoben, das ich in die Vue-Datei importiere. In diesem utils.js möchte ich den Vuex-Zustand lesen. Wie kann ich das machen? Wie es aussieht, nähert sich der Zustand mit Gettern usw. an, dass Sie innerhalb einer vue-Komponente arbeiten, oder nicht?Wie bekomme ich Vuex-Status von einer Javascript-Datei (anstelle einer Vue-Komponente)

Ich habe versucht, import state from '../store/modules/myvuexmodule' und dann auf state.mystateproperty verweisen, aber es gibt immer 'undefined', während in den vue-Devtools kann ich sehen, dass die Zustandseigenschaft richtige Werte hat.

Meine Schätzung an dieser Stelle ist, dass dies einfach nicht der Weg zu gehen ist, da der Wert von state.property in der js-Datei nicht reaktiv ist und daher nicht aktualisiert oder etwas, aber vielleicht kann jemand bestätigen/beweisen ich falsch.

+0

ich voll und ganz verstehe nicht, wie ich die Dateien nicht sehen kann, aber vue.use (vuex) aufaddiert vuex auf alle Ihre vue Komponenten. Das könnte ein Grund sein, warum Ihre utils.js keinen Zugriff darauf hätte. Ich lasse externe Funktionen Teil von Aktionen sein, die den Zustand als Argumente annehmen und den Wert für die Mutation zurückgeben. –

+0

Es gibt keine Demo-Dateien, da es sich um ein "allgemeines Problem" handelt. Und ja, ich weiß, wie ich das in einer Vue-Datei lösen kann, aber meine Frage ist, wie man den Status in einer js-Datei bekommt. Ihre 'Lösung' ist mir nicht klar; Es sieht so aus, als würden Sie sich innerhalb der Vue-Datei dem Status nähern (mit 'externen Funktionen'). Ich möchte jedoch (wenn möglich) den vue-Status aus einer js-Datei heraus ansprechen. – musicformellons

+0

Ja, ich möchte den Zustand nicht extern ändern. Kannst du eine Vorstellung davon geben, was für eine Art von Arbeit du in Sachen Arbeit machst? Weil ich das Gefühl habe, vuex-Aktionen oder Mutationen zu verwenden, würde es unnötig sein, einen Status außerhalb des vuex-Speichers zu erhalten. –

Antwort

10

Es ist möglich, den Speicher als ein Objekt in einer externen js-Datei zuzugreifen, ich habe auch einen Test hinzugefügt, um die Änderungen in dem Zustand zu veranschaulichen.

hier ist die externe js-Datei:

import { store } from '../store/store' 

export function getAuth() { 
    return store.state.authorization.AUTH_STATE 
} 

Die Zustandsmodul:

import * as NameSpace from '../NameSpace' 
/* 
    Import everything in NameSpace.js as an object. 
    call that object NameSpace. 
    NameSpace exports const strings. 
*/ 

import { ParseService } from '../../Services/parse' 

const state = { 
    [NameSpace.AUTH_STATE]: { 
    auth: {}, 
    error: null 
    } 
} 

const getters = { 
    [NameSpace.AUTH_GETTER]: state => { 
    return state[NameSpace.AUTH_STATE] 
    } 
} 

const mutations = { 
    [NameSpace.AUTH_MUTATION]: (state, payload) => { 
    state[NameSpace.AUTH_STATE] = payload 
    } 
} 

const actions = { 
    [NameSpace.ASYNC_AUTH_ACTION]: ({ commit }, payload) => { 
    ParseService.login(payload.username, payload.password) 
     .then((user) => { 
     commit(NameSpace.AUTH_MUTATION, {auth: user, error: null}) 
     }) 
     .catch((error) => { 
     commit(NameSpace.AUTH_MUTATION, {auth: [], error: error}) 
     }) 
    } 

export default { 
    state, 
    getters, 
    mutations, 
    actions 
} 

Shop:

import Vue from 'vue' 
import Vuex from 'vuex' 
import authorization from './modules/authorization' 

Vue.use(Vuex) 

export const store = new Vuex.Store({ 
    modules: {   
    authorization  
    }     
})     

Bisher alles, was ich getan habe, ist eine js-Datei erstellen welche eine Funktion exportiert, die die AUTH_STATE Eigenschaft der authorization Statusvariable zurückgibt.

Eine Komponente für die Prüfung:

<template lang="html"> 
    <label class="login-label" for="username">Username 
     <input class="login-input-field" type="text" name="username" v-model="username"> 
    </label> 
    <label class="login-label" for="password" style="margin-top">Password 
     <input class="login-input-field" type="password" name="username" v-model="password"> 
    </label> 
    <button class="login-submit-btn primary-green-bg" type="button" @click="login(username, password)">Login</button> 
</template> 

<script> 
import { mapActions, mapGetters } from 'vuex' 
import * as NameSpace from '../../store/NameSpace' 
import { getAuth } from '../../Services/test' 

export default { 
    data() { 
    return { 
     username: '', 
     password: '' 
    } 
    }, 
    computed: { 
    ...mapGetters({ 
     authStateObject: NameSpace.AUTH_GETTER 
    }), 
    authState() { 
     return this.authStateObject.auth 
    }, 
    authError() { 
     return this.authStateObject.error 
    } 
    }, 
    watch: { 
    authError() { 
     console.log('watch: ', getAuth()) // ------------------------- [3] 
     } 
    }, 
    authState() { 
     if (this.authState.sessionToken) { 
     console.log('watch: ', getAuth()) // ------------------------- [2] 
     } 
    }, 
    methods: { 
    ...mapActions({ 
     authorize: NameSpace.ASYNC_AUTH_ACTION 
    }), 
    login (username, password) { 
     this.authorize({username, password}) 
     console.log(getAuth())    // ---------------------------[1] 
    } 
    } 
} 
</script> 

auf dem Klick Standardzustand Taste auf der Konsole angemeldet. Die Aktion in meinem Fall führt zu einem API-Aufruf, was zu einer Statusänderung führt, wenn die Kombination Benutzername - Passwort einen Datensatz enthält.

Ein erfolgreicher Fall zeigt die Konsole in authState Uhr an, die importierte Funktion kann die an den Status vorgenommenen Änderungen drucken.

Ebenso auf einem Fall versagen, die Uhr auf authError zeigt die an den Staat vorgenommenen Änderungen

+1

Danke für Ihre Antwort! Sieht großartig aus. Ich denke, ich importiere Staat statt Laden ...Ich folgte einem der vuex Beispiele: https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/store/index.js Es gibt dem Geschäft keinen Namen, also sollte ich wahrscheinlich tun Das!? – musicformellons

+0

Mmmh, denke ich Ändern A: '' 'Exportstandard neue Vuex.Store ({ Aktionen, Getter, Module: { Wagen, Produkte }, streng: debug, Plugins: debug [createLogger()] [] }) '' ' in B: ' '' Export konst store = new Vuex.Store ({ Aktionen, Getter, Module: { Wagen, Produkte }, strenge : debug, plugins: debug? [createLogger()]: [] }) '' 'wird meine Referenzen in anderen Dateien vermasseln ... irgendeine Idee, wie man den Laden im Falle von A referenziert? – musicformellons

+0

Das ist mehr in Richtung der Verwendung von named exports vs defaults. Wenn die Datei nur einen Export hat, wird empfohlen, das Export-Standardformat zu verwenden, wie Sie in der Beispielverknüpfung sehen. Ich tat dies wegen meiner Gewohnheit, benannte Exporte überall zu benutzen. –

Verwandte Themen