Nuxt 从 JS 文件访问存储(在模块模式下)

Nic*_*ter 6 vue.js vuex nuxt.js vuex-modules

我有一个 AuthService,在 Nuxt 应用程序的命名空间存储中使用。我需要将 AuthService 的突变提交到命名空间存储,但我不知道如何将存储导入到我的 AuthService 中。

我见过将商店导入 JS 文件的示例,但商店是在 Vue 应用程序中显式定义的。因为我在商店中使用 Nuxt 的模块模式,所以我不确定可以将商店导入 AuthService 文件的根路径。据我了解,当使用“模块模式”时,Nuxt 会在幕后处理创建根存储和所有命名空间存储

我的 Nuxtstore目录包括index.js(它是空的)并且auth.js其中包含我想从 AuthService 调用的突变。

auth.js

import AuthService from '../firebase/authService'

const authService = new AuthService()

export const state = () => ({
  user: null
})

export const mutations = {
  setUser (state, user) {
    state.user = user
  }
}

export const actions = {
  async signUp ({ commit }, payload) {
    try {
      await authServices.createUser(payload)
      return Promise.resolve()
    } catch (err) {
      const notification = {
        duration: 5000,
        message: err.message,
        type: 'error'
      }
      commit('ui/activateNotification', notification, { root: true })
      return Promise.reject()
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

authService.js

import { fAuth, fDb } from './config'

// I think I need to import auth store here but I'm not sure how

export default class AuthClient {
  async createUser (payload) {
    try {
      const res = await fAuth.createUserWithEmailAndPassword(payload.email, payload.password)
      const { uid } = res.user
      const user = {
        ...payload,
        uid
      }
      await this._createUserDoc(user)
      this._initAuthListener()
      return Promise.resolve()
    } catch (err) {
      return Promise.reject(err)
    }
  }

  async _createUserDoc (user) {
    await fDb.collection('users').doc(user.uid).set(user)
  }

  _initAuthListener () {
    fAuth.onAuthStateChanged(async (user) => {
      try {
        if (user) {
          const userProfileRef = fDb.collection('users').doc(user.uid)
          const userProfileDoc = await userProfileRef.get()
          const { uid, userName } = userProfileDoc.data()

          // Here is where I want to call a mutation from the auth store

          this.store.commit('setUser', {
            uid,
            userName
          })
        } else {
          this.store.commit('setUser', null)
        }
      } catch (err) {
        console.log(err)
      }
    })
  }
}

Run Code Online (Sandbox Code Playgroud)

Egg*_*gon 6

我想提出一个使用插件的解决方案。

在外部模块 ( externalModule.js) 中,我们定义store变量并导出一个接收参数init的函数。Nuxt context该函数将storefrom分配context给现在可以在模块中使用的变量:

let store;
export function init (context) {
    store = context.store;
};
(...further business logic using store)
Run Code Online (Sandbox Code Playgroud)

然后在插件文件夹中我们创建一个插件文件(我们称之为storeInit.js)。该文件init从外部模块导入函数并导出Nuxt所需的默认插件函数。该函数从 Nuxt 接收数据context,我们调用该init函数进一步传递context

import { init } from '[pathTo]/externalModule.js';
export default (context, inject) => {
    init(context);
};
Run Code Online (Sandbox Code Playgroud)

然后我们在文件中注册插件nuxt.config.js

module.exports = {
    ...
    plugins: [
        { src: '~/plugins/storeInit' }
    ],
    ...
}
Run Code Online (Sandbox Code Playgroud)

这样,当 Nuxt 构建应用程序并注册插件时,context对象将传递到外部模块,我们可以使用其中的任何内容,其中包括store.


Han*_*bib 2

在商店文件夹中的文件中,index.js您需要像这样返回商店

import Vuex from 'vuex'
const createStore = () => {
  return new Vuex.Store({
    state: {
      counter: 0
    },
    mutations: {
      increment (state) {
        state.counter++
      }
    }
  })
}

export default createStore
Run Code Online (Sandbox Code Playgroud)

在你的authService.js文件中你需要像这样导入商店

import $store from '~/store'
Run Code Online (Sandbox Code Playgroud)

这样您就可以访问您的商店

$store.commit('setUser', null)
Run Code Online (Sandbox Code Playgroud)

我希望这对你有用

重要提示:您不需要安装 vuex,因为它已经随 nuxtjs 一起提供

  • 但这不会破坏 Nuxt 构建过程吗?Nuxt 指定商店的“index.js”应该是什么样子,并期望它导出商店的主要属性(状态、突变等),并从中创建商店的实例。它不需要已经创建的实例。 (3认同)