Vuex存储和访问Vue.prototype

时间:2020-09-12 14:41:59

标签: javascript vue.js vuex

我将开始使用Vue。我尝试在其他帖子中找到解决方案,但没有成功。所以:

我有2部分代码:

//main.js
...
    const axiosInstance = axios.create({
        mode: 'no-cors',
        baseURL: process.env.VUE_APP_BASE_URL,
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
    })
    
    Vue.prototype.$http = axiosInstance
    Vue.config.productionTip = false
    
    new Vue({
      router,
      store,
      vuetify,
      i18n,
      render: h => h(App),
    }).$mount('#app')

//store.js
export default new Vuex.Store({
...
    actions: {
      [AUTH_REQUEST]: ({commit, dispatch}, user) => {
        return new Promise((resolve, reject) => {
          commit(AUTH_REQUEST)
          this.$http.post('/auth/login', user)
            .then(resp => {...}
        })
    }
})

当我在组件方法中触发this.$store.dispatch(AUTH_REQUEST, ...)时,我在控制台中看到错误,例如Uncaught (in promise) TypeError: Cannot read property '$http' of undefined。 我尝试过this.$httpthis._vm.$http-一样。

4 个答案:

答案 0 :(得分:0)

问题在于,将axiosInstance附加到Vue.prototype使其仅在后续子vue组件中可用,而在商店中不可用。

要从商店访问axiosInstance,您需要将其导入。 一种方法是将axios实例重构为自己的文件,并将该文件包含在main.js中,以便执行该文件。 然后在新创建的axios文件中,导出axiosInstance,以便可以由存储文件导入。

HTH

答案 1 :(得分:0)

您只能在vue js组件中访问此实例。之后,您需要将axios包装到另一个js文件,然后再导入vuex文件。我这样使用非常有用。

答案 2 :(得分:0)

感谢您的回答。我是这样的

//utils/axiosHelper.js
import Vue from 'vue';
import axios from 'axios';
import router from '@/router';

const axiosInstance = axios.create({
  // withCredentials: true,
  mode: 'no-cors',
  baseURL: 'correctUrl',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    // 'Access-Control-Allow-Origin': '*',
  },
})

axiosInstance.interceptors.request.use(
  config => {
    if (!config.url.includes('auth')) {
      if (localStorage.getItem('user-token') !== null) {
        config.headers['Authorization'] = localStorage.getItem('user-token')
      }
    }
    return config;
  })

axiosInstance.interceptors.response.use(
  resp => {
    return resp
  }, error => {
    if (error.response.status === 401) {
      router.push('/auth/login');
      localStorage.setItem('isAdmin', null);
      localStorage.setItem('user-token', null);
    } else if (error.response.status >= 400) {
      console.log(error.response.data);
      alert(error.response.data.error);
    }
    return Promise.reject(error);
  })

Vue.prototype.$http = axiosInstance;

export default Vue.prototype.$http;

然后

//store.js
...
import $http from '@/utils/axiosHelper'
...
export default new Vuex.Store({
  ...
  actions: {
    [AUTH_REQUEST]: ({commit, dispatch}, user) => {
      return new Promise((resolve, reject) => {
        commit(AUTH_REQUEST)
        this.$http.post('/auth/login', user)
          .then(resp => {...})
      })
    },
  ...
})

然后

//main.js
...
import $http from "@/utils/axiosHelper"
...
Vue.use($http)

当我尝试触发Cannot read property '$http' of undefined

时,仍然看到AUTH_REQUEST

答案 3 :(得分:0)

如上所述,您应该将 Axios 实例化代码移动到它自己的文件中。

文件:app/src/libs/axios.js

import Vue from 'vue'

// axios
import axios from 'axios'
import updateToken from '@/auth/middleware/updateToken'

const axiosIns = axios.create({
  // You can add your headers here
  // ================================
  // baseURL: 'https://some-domain.com/api/',
  // timeout: 1000,
  // headers: { 'X-Custom-Header': 'foobar' },
})

// Or you can use an interceptor if adding tokens etc.
// ======================================
axiosIns.interceptors.request.use(async config => {
  const token = await updateToken()
  config.headers.common.Authorization = `Bearer ${token}`
  return config
})

Vue.prototype.$http = axiosIns

export default axiosIns

文件:app/src/store/index.js

...
import axiosIns from '@/libs/axios'

axiosIns.get('/some/url').then(data => { console.log(data) })
...