2017-01-08 3 views
7

Я работаю с vuex (2.1.1) и получаю все, что работает в vue отдельных компонентах файла. Однако, чтобы избежать слишком большого крутизны в одном компоненте vue, я переместил некоторые функции в модуль utils.js, который я импортирую в файл vue. В этом utils.js я хотел бы прочитать состояние vuex. Как я могу это сделать? Как кажется, приближение к состоянию с геттерами и т. Д. Предполагает, что вы работаете из компонента vue или нет?Как получить состояние vuex из файла javascript (вместо компонента vue)

Я пытался использовать import state from '../store/modules/myvuexmodule', а затем ссылаюсь на state.mystateproperty, но он всегда дает «undefined», тогда как в vue-devtools я вижу, что свойство состояния имеет правильные значения.

Моя оценка на этом этапе заключается в том, что это просто не «путь», поскольку значение state.property в файле js не будет реактивным и, следовательно, не будет обновляться или что-то в этом роде, но, возможно, кто-то может подтвердить/доказать я ошибаюсь.

+0

Я не в полной мере понять, как я не могу видеть ваши файлы, но vue.use (vuex) добавляет vuex все ваши вю компоненты. Это может быть причиной того, что ваш utils.js не будет иметь к нему доступа. Я позволяю внешним функциям быть частью действий, которые принимают состояние как аргументы и возвращают значение для мутации. –

+0

Нет демо-файлов, так как это «общая проблема». И да, я знаю, как решить это в VUE-файле, но мой вопрос: «Как получить состояние в js-файле». Ваше «решение» мне не понятно; кажется, что вы просто приближаетесь к состоянию в файле vue (используя «внешние функции»). Тем не менее, я хочу (если возможно) приблизить состояние vue из js-файла. – musicformellons

+0

Да, я предпочитаю не изменять состояние извне. Можете ли вы дать представление о том, какую работу вы делаете в утилях? Поскольку я сильно чувствую, что действия vuex или мутации устраняют необходимость получения состояния вне хранилища vuex. –

ответ

10

Доступ к хранилищу возможен как объект во внешнем js-файле, я также добавил тест для демонстрации изменений состояния.

здесь внешний JS файл:

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

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

состояние модуля:

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 
} 

Магазин:

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

Vue.use(Vuex) 

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

До сих пор все, что я сделал, это создать файл JS который экспортирует функцию, возвращающую свойство AUTH_STATE переменной состояния authorization.

Компонент для тестирования:

<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> 

На состояния кнопки нажмите по умолчанию записывается на консоль. Действие в моем случае приводит к вызову api, в результате чего изменяется состояние, если комбинация имени пользователя и пароля имела запись.

Успешный случай приводит к отображению консоли в authState watch, импортированная функция может печатать изменения, внесенные в состояние.

Кроме того, на неисправностью случае, часы на authError будут показаны изменения, внесенные в состояние

+1

Спасибо за ваш ответ! Выглядит отлично. Я думаю, что я импортирую состояние вместо хранилища ...Я последовал за одним из примеров vuex: https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/store/index.js Это не дает магазину имя, поэтому, вероятно, мне следует сделать что!? – musicformellons

+0

Ммммы, я думаю, что изменение A: '' 'экспорт по умолчанию нового Vuex.Store ({ действия, Геттеров, модулей: { корзины, продуктов }, строго: отладка, плагин:? Отлаживать [createLogger()]: [] }) '' ' в B: ' '' экспорт Const магазин = новый Vuex.Store ({ действия, геттеры, модули: { корзины, продукты }, строги : debug, плагины: debug? [createLogger()]: [] }) '' 'будет испортить мои ссылки в других файлах ... любая идея, как ссылаться на магазин в случае A? – musicformellons

+0

Это больше похоже на то, когда использовать именованный экспорт по умолчанию. Если файл имеет только один экспорт, рекомендуется использовать формат экспорта по умолчанию, как вы видите в ссылке примера. Я сделал это из-за своей привычки использовать именованный экспорт во всем мире. –

Смежные вопросы