【问题标题】:How to get vuex state from a javascript file (instead of a vue component)如何从 javascript 文件(而不是 vue 组件)获取 vuex 状态
【发布时间】:2017-05-22 21:51:49
【问题描述】:

我正在使用 vuex (2.1.1) 并在 vue 单文件组件中工作。但是,为了避免我的 vue 单文件组件中出现太多杂乱无章的内容,我将一些函数移到了 utils.js 模块,我将其导入到 vue 文件中。在这个utils.js我想读一下vuex的状态。我怎样才能做到这一点?由于似乎使用 getter 等接近状态,因此假设您是在 vue 组件中工作,或者不是?

我尝试 import state from '../store/modules/myvuexmodule' 然后引用 state.mystateproperty 但它总是给出“未定义”,而在 vue-devtools 中我可以看到 state 属性确实具有正确的值。

我在这一点上的估计是,这根本不是“要走的路”,因为 js 文件中的 state.property 值不会是反应性的,因此不会更新或其他什么,但也许有人可以确认/证明我错了。

【问题讨论】:

  • 我不完全理解,因为我看不到你的文件,但是 vue.use(vuex) 将 vuex 添加到你所有的 vue 组件中。这可能是您的 utils.js 无法访问它的原因。我让外部函数成为动作的一部分,它们将状态作为参数并返回变异值。
  • 没有演示文件,因为这是一个“一般问题”。是的,我确实知道如何在 vue 文件中解决这个问题,但我的问题是“如何在 js 文件中获取状态”。我不清楚您的“解决方案”;看来您只是在接近 vue 文件中的状态(使用“外部函数”)。但是,我想(如果可能)从 js 文件中处理 vue 状态。
  • 是的,我不想从外部改变状态。您能否介绍一下您在 utils 中所做的工作类型?因为我强烈认为使用 vuex 操作或突变将消除获取 vuex 存储之外的状态的需要。
  • 我编辑了这个问题。我只想在 js 文件中读取/评估 vuex state.property 值(用于在函数内的 if 子句中进行评估),而不是通过操作/突变来改变它。

标签: javascript vue.js vue-component vuejs2 vuex


【解决方案1】:

可以在外部js文件中作为对象访问store,我还加了一个测试来演示状态的变化。

这里是外部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 文件,该文件导出一个函数,该函数返回 authorization 状态变量的 AUTH_STATE 属性。

用于测试的组件:

<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手表中显示控制台,导入的函数可以打印对状态所做的更改。

同样,在失败的情况下,authError 上的手表将显示对状态所做的更改

【讨论】:

  • 感谢您的回答!看起来很棒。我想我正在导入状态而不是存储...我遵循了一个 vuex 示例:github.com/vuejs/vuex/blob/dev/examples/shopping-cart/store/… 它没有给存储命名,所以我应该这样做!?
  • 嗯,我认为将 A:export default new Vuex.Store({ actions, getters, modules: { cart, products }, strict: debug, plugins: debug ? [createLogger()] : [] }) 更改为 B:export const store = new Vuex.Store({ actions, getters, modules: { cart, products }, strict: debug, plugins: debug ? [createLogger()] : [] }) 会搞砸我在其他文件中的引用...知道在 A 的情况下如何引用商店吗?
  • 这更像是何时使用命名导出与默认值。如果文件只有一个导出,建议使用示例链接中的导出默认格式。我这样做是因为我习惯在任何地方都使用命名导出。
  • 因此,如果您使用了“A”格式,那么您导入的名称(如import someName from '../store')应该是商店。请注意,在 import 语句中是 someName 而不是 { someName }
  • 感谢您的详细回答,非常有帮助。我在我的 Vuex 商店中使用 export default 语法,并且需要进行一些实验才能使语法恰到好处,所以在这里分享一个摘要。所以我的 Vuex 商店看起来像:./store/index.js:export default new Vuex.Store({...}); 然后在我的 .js 文件中引用:import store from '../store/index'; ... const test = store.state.someGetter;(Blech 试图在评论中格式化代码......)
【解决方案2】:

对于想知道如何从 javascript 文件中访问突变的任何人,您可以执行以下操作:

import store from './store'
store.commit('mutation_name', mutation_argument);

或者对于动作,

store.dispatch('action_name', action_argument)

【讨论】:

    【解决方案3】:
    import store from './store'
    

    store.commit('mutation_name', mutation_argument)
    

    如果你使用js文件

    【讨论】:

      【解决方案4】:

      您还可以访问以下操作:

      import store from './store'
      store.dispatch('action_name', action_argument)
      

      【讨论】:

        猜你喜欢
        • 2017-07-30
        • 2021-03-16
        • 2018-03-24
        • 1970-01-01
        • 2021-02-10
        • 2020-12-07
        • 2021-10-28
        • 2023-03-20
        • 2017-01-10
        相关资源
        最近更新 更多