【问题标题】:How to use vuex action in function如何在函数中使用 vuex 动作
【发布时间】:2019-08-08 19:50:56
【问题描述】:

我是 Vue 的新手,所以我很可能误解了一些东西。我想在 App.vue 的本地函数中调用 vuex 操作,如下所示:

<template>
  <div id="app">
    <button @click="runFunction(1)">Test</button>
  </div>
</template>

<script>
import { mapActions } from 'vuex'

export default{
  data() { return { } },
  methods: {
      ...mapActions(['doAction']),
      buttonClicked: (input) => { runFunction(input) }
  }
}

function runFunction(input){
  doAction({ ID: input });
}
</script>

该操作调用store.js 中的突变

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    IDs: []
  },
  mutations: {
    doAction: (state, id) => { state.IDs.push(id) }
  },
  actions: {
    doAction: ({ commit }, id) => { commit('doAction', id) }
  }
})

我还有一个 main.js 来设置 vue:

import Vue from 'vue'
import App from './App.vue'
import store from './store'

new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

我得到的错误是:

ReferenceError: doAction is not defined
  at runFunction

如何在函数内调用映射的操作?版本为 Vue 2.6.10

【问题讨论】:

    标签: vuejs2 vuex


    【解决方案1】:

    runFunction 定义为“本地函数”有几个问题:

    function runFunction(input){
      doAction({ ID: input });
    }
    

    首先,这只是一个普通的 JavaScript 函数,并且适用通常的范围规则。 doAction 需要在某个函数可以看到的地方定义。此函数与App.vue 中定义的组件之间没有神奇的联系。组件中的代码(例如 buttonClicked 中的代码)可以访问该函数,但反之则不行。

    下一个问题是它在您的模板中不可用。当您在将要查找this.runTemplate(1) 的模板中写入runTemplate(1) 时,尝试在当前实例上解决它。您的函数不在当前实例上。鉴于您的模板包含 @click="runFunction(1)",我有点惊讶您没有看到控制台错误警告单击处理程序未定义。

    mapActions 使用this.$store 中保存的引用访问存储。当您将store 添加到您的new Vue({store}) 时,将创建该引用。商店似乎可以通过魔法获得,但实际上只是this.$store,其中this 是当前组件。

    目前还不清楚您为什么要尝试在组件之外编写此函数。最简单的解决方案是将其添加到methods。然后它将可用于模板,您可以以this.doAction 的身份访问doAction

    要将其保留为单独的功能,您需要为其提供某种对商店的访问权限。在不知道您为什么希望它首先分开的情况下,不清楚如何最好地实现这一点。

    【讨论】:

    • 实际上没有理由让它成为一个单独的函数,但实际上它最终会有点长。我尝试将其更改为buttonClicked: (input) =&gt; { this.doAction({ ID: input }); } 并得到TypeError: _this.doAction is not a function
    • @DavidStarkey 那是因为您使用的是箭头函数。应该是buttonClicked (input) { this.doAction({ID: input}) }
    • 就是这样。半开始理解它。
    【解决方案2】:

    当然它不是在你的实例之外定义的......你必须在你的函数组件上从store.js 导入导出的store

    <script>
    import { mapActions } from 'vuex'
    
    import store from 'store.js'
    
    export default{
      data() { return { } },
      methods: {
          ...mapActions(['doAction']),
          buttonClicked: (input) => { runFunction(input) }
      }
    }
    
    function runFunction(input){
      store.commit({ ID: input });
    }
    </script>
    

    【讨论】:

    • 我没有在 OP 中提到这一点,但是在 new Vue({ el: '#app', store, render: h =&gt; h(App) }) 中存储 main.js 有什么用呢?
    • @DavidStarkey 您的 vue 实例的 thisexport 块之外未定义
    • @DavidStarkey new Vue({ el: '#app', store, render: h => h(App) }) 只是将您导出的商店设置为实例商店,所以this.$store = store
    • @DavidStarkey 你试过代码但没用吗?
    • 如果您只是要直接使用商店,我只是不确定采取行动和使用mapActions 的意义何在。为什么不在那个时候做store.state.IDs.push
    猜你喜欢
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 2020-10-20
    • 2022-01-27
    • 2021-09-16
    • 1970-01-01
    • 2021-01-06
    • 2021-09-02
    相关资源
    最近更新 更多