在 Javascript ES6 模块中访问 Vuex 操作

Posted

技术标签:

【中文标题】在 Javascript ES6 模块中访问 Vuex 操作【英文标题】:Accessing Vuex action in Javascript ES6 module 【发布时间】:2021-12-29 23:27:12 【问题描述】:

我正在使用 NuxtJS 框架来构建一个 Vue 应用程序。我为TinyMCE 编辑器编写了一个自定义插件,用于将图像上传到服务器。这个插件是一个带有单个导出的 ES6 模块(为简洁起见,我已经删除了代码)。所以这里选择图片 -> 压缩 -> 上传到服务器。

  import  actions  from '@/store/common/post_editor.js'

  const imageUpload = function (editor) 

    function _onAction() 
      let imageBlob = null
       onChange: function (api, details) 
          //get the image selected
          compressImage(image).then((output) => 
          imageBlob = output
        )
      
    ,
    onSubmit: function (api) 
        actions
          .uploadToServer(imageBlob)
          .then((url) => 
            editor.insertContent('<p><img src="' + url + '"/></p>')
          )
          .catch((error) => 
          )
      ,
    )
  
 

export  imageUpload 

我在将图像上传到服务器的模块中导入 Vuex action。以下是它的代码。

uploadToServer(vuexContext, blob) 
return new Promise((resolve, reject) => 
  let formData = new FormData()
  formData.append('file', blob)
  console.log(this.$axios) // this is undefined
  this.$axios
    .$post('/server/upload', formData, 
      headers: 
        'Content-Type': 'multipart/form-data',
      ,
    )
    .then((res) => 
      resolve(res.location)
    )
    .catch((error) => 
      reject(error)
    )
  )

但是在使用这个插件的时候,axios没有被触发。显然原因是this.$axiosundefined。因此,这似乎不是将 Vuex 操作导入 ES6 模块的正确方法。

感谢您的帮助。

编辑

目前,我正在使用 window.$nuxt.context.store .dispatch('common/post_editor/uploadToServer', imageBlob)

但不确定这是否是一个好习惯。

【问题讨论】:

您可以在组件中访问 this.$axios。您发布的代码不是组件。你根本不需要 this.$axios。只需导入它,这就是模块的用途 @EstusFlask this.$axios 在我正在导入的 Vuex 操作中未定义。当从 Vue 组件或其他 Vuex 操作调用时,它可以正常工作。 因为this 需要成为组件实例才能接收插件属性,而在发生操作时显然不是。 @EstusFlask this 指的是 Store 实例。 没错。它不是组件实例,也不应该有它们的属性。可能有全局 $axios axios.nuxtjs.org/usage/#-shortcuts 但我没有检查它,我不会使用它,因为在模块化环境中依赖任意全局变量也不是一个好习惯。 【参考方案1】:

Vue 和 Nuxt 插件在组件实例上定义属性。动作中的this 不是组件实例,因此不应该有this.$axios。除了严格的 OOP 代码之外,在任何地方使用松散定义的 this 动态上下文是一种过时且有问题的做法。

你使用动作的方式不正确。应导入商店而不是操作:

import store from '.../store`.

导入 Axios 的方式不正确。它应该在非组件模块中显式导入。如果有带有拦截器等的Axios实例,可以在一个模块中维护:

import axios from '.../common/axios`.

【讨论】:

我想你误会了。这不是 VueJS 插件,而是 TinyMCE 插件,它是一个 ES6 模块。 当提到插件时,答案是指 Axios Nuxt/Vue 插件。另一件事是 TinyMCE 插件无关紧要。正如你所说,它只是 ES 模块。 从商店作品中导入动作。但是导入商店import store from '@/store/common/post_editor.js' 会给出警告export 'default' (imported as 'store') was not found in '@/store/common/post_editor.js'。这是真的store 不是存储文件中的默认导出。 我不知道您这边的模块是如何构建的。您只需要从定义它的模块导入商店。我没有注意到的另一件事是动作被滥用。 uploadToServer(vuexContext, blob) 是 Vuex 操作,对吗?动作应该修改状态而不返回结果。否则根本没有理由使用 Vuex 全局状态。

以上是关于在 Javascript ES6 模块中访问 Vuex 操作的主要内容,如果未能解决你的问题,请参考以下文章

深入理解ES6之《用模块封装代码》

JavaScript ES6中export及export default的区别

es6中的模块化

具有javascript依赖关系的lit-element,未打包为es6模块(尚未)

基于ES6,使用ReactWebpackBabel构建模块化JavaScript应用

本地文件中的 ES6 模块 - 服务器以非 JavaScript MIME 类型响应