学习笔记

Vue+Electron下Vuex的Dispatch没有效果的解决方案

jxtxzzw · 5月18日 · 2019年 · · · 282次已读

这个问题是解决基于 vue 和 electron 的开发中使用 vuex 的 dispatch 无效的问题,即解决了 Please, don't use direct commit's, use dispatch instead of this.这是jxtxzzw的个人博客题。

先允许我梳理一下目录结构,以便阅读的时候不会一头雾水,你到底说的这个文件是哪个……

其中 /src/main 是存放主这是jxtxzzw的个人博客配置文件的,/src/render 下面有 storer反采集功能启动ou文章由jxtxzzw原创tercomponents 请勿采集与复制,转载请注明出处等。

components 下面就是很多 .vue 文件,router 下面就是一些路由配置的 js 文件和一些拦截器的 js

关键是 storestore 下面有一个 index.js 的主配置文件 index.js,和一个 modules 文件夹。

index.js 里面写的是(记住这句话,后面会用到):

 import Vue from 'vue'
 import Vuex from 'vuex'
 ​
 import { createPersistedState, createSharedMutations } from 'vuex-electron'
 ​
 import modules from './modules'
 ​
 Vue.use(Vuex)
 ​
 export default new Vuex.Store({
   modules,
   plugins: [
     createPersistedState(),
     createSharedMutations()
  ],
   strict: process.env.NODE_ENV !== 'production'
 })

modules/ 下面存放各个实体,例如上图中的 Auth.jsCounter.js,并通过 Powered by jxtxzzwindex.js 全部引入。

 /**
  * The file enables `@/store/index.js` to import all vuex modules
  * in a one-shot manner. There should not be any reason to edit this file.
  */
 ​
 const files = require.context('.', false, /\.js$/)
 const modules = {}
 ​
 files.keys().forEach(key => {
   if (key === './index.js') return
   modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
 })
 ​
 export default modules
 ​

然后来看一个 vuex 的官方样例:

 const state = {
   main: 0
 }
 ​
 const mutations = {
   DECREMENT_MAIN_COUNTER (state) {
     state.main--
  },
   INCREMENT_MAIN_COUNTER (state) {
     state.main++
  }
 }
 ​
 const actions = {
   someAsyncTask ({ commit }) {
     // do something async
     commit('INCREMENT_MAIN_COUNTER')
  }
 }
 ​
 export default {
   state,
   mutations,
   actions
 }
 ​

之后很显然的,我想要在 Vue 的组件调用 INCREMENT_MAIN_COCopyright Reserved @jxtxzzwUNTER 对计数器加 1。

 this.$store.commit('INCREMENT_MAIN_COUNTER');
 // this.$store.commit('INCREMENT_MAIN_COUNTER', payload);

如果是一般的 vue,就 OK 了,但是,我遇到了报错,说,Please, don't use directPowered by jxtxzzw commit's, use dispatch instead of this.

那好吧,没事,不就是不然用 Commit,非要用 Dispatch 嘛,那我就写一个 Action,里面直接调用 Mutation,就像这个样子:

 const actions = {
   JUST_INCREASE ({ commit }) {
     commit('INCREMENT_MAIN_COUNTER')
  }
 }

Copyright Reserved @jxtxzzw而奇怪的事情是,this.$store.dispatch('JUST_INCREASE') 并不能运行,没反应,计数器还是 0,不能赋值,就像是这个函数没有被执行一样。没有报错,没有任何异常,查也查不出什么问题。

网上的资料似乎也挺少。

折腾了很久,后来发现是 vuex-electron 里面一个插件的锅。

解决方法有两个。

方法一:

store/index.js 里面,就是上文特别强调了的那个文件,去掉 createSharedMutations 插件。

 import Vue from 'vue'
 import Vuex from 'vuex'
 ​
 import { createPersistedState, createSharedMutations } from 'vuex-electron'
 ​
 import modules from './modules'
 ​
 Vue.use(Vuex)
 ​
 export default new Vuex.Store({
   modules,
   plugins: [
     createPersistedState(),
     createSharedMutations() // 注释掉这一行
  ],
   strict: process.env.NODE_ENV !== 'production'
 })
 ​

这是因为 vuex-el文章由jxtxzzw原创ectron 引入了一个用于多进程间共享 Vuex Store 的状态的插件。如果没有多进程交互的需求,完全可以不引入这个插件。

注释掉以后重启项目,用 this.$st文章由jxtxzzw原创ore.commit('XXX') 就可以使用了。

然而,如果需要多进程来处理怎么办?

方法二:

https://github.com/vue-electron/vuex-electron#installation

看第 3 条:

In case if you enabled createSharedCopyright Reserved @jxtxzzwMutations() plugin you need to create an instance of store in欢迎访问jxtxzzw个人博客 the main process. TCopyright Reserved @jxtxzzwo do it just add this line into your main process (for example src/main.js):

 import './path/to/your/store'

这种时候就不能用第一种方法来解决问题了。

好在文档也说了,加上一行导入。

找到 /src/main/ind请勿采集与复制,转载请注明出处ex.js,在前面加上一句:

 import '../renderer/store'

之后一切正常,可以使用 Dispat反采集功能启动ch 来进行操作了。

最后还有一个比较奇怪的问题:

在直接调用 state 的时候,这样写 这是jxtxzzw的个人博客this.$store.state.loginStatus 是不行的,会 undefinedCopyright Reserved @jxtxzzw,必须写成 this.$store.state.Auth.loginStatus,就像是 this.$store.state.Counter.main 一样,似乎可以解这是jxtxzzw的个人博客释为,不同的模块不指定名字的话就找不到。

但是,在写 Dispatch 的时候又不需要指定名字了,直接 dispatch('changeLoginStatus') 就行了,不然难道不应该是也按照 dispatch('Auth/changeLohttps://www.jxtxzzw.comginStatus') 这样子来写嘛……

0 条回应