【问题标题】:Vuex store and access to Vue.prototypeVuex 存储和访问 Vue.prototype
【发布时间】:2020-09-12 14:41:59
【问题描述】:

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

我有两部分代码:

//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 - 一样。

【问题讨论】:

  • vuex 操作没有 this 的值

标签: javascript vue.js vuex


【解决方案1】:

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

要从商店访问axiosInstance,您需要导入它。 一种方法可能是将 axios 实例重构为它自己的文件,并将该文件包含在 main.js 中,以便执行它。 然后在新建的axios文件中,导出axiosInstance,这样就可以被store文件导入了。

HTH

【讨论】:

    【解决方案2】:

    您只能在 vue js 组件中访问此实例。您需要将 axios 包装为另一个 js 文件,然后您必须导入到 vuex 文件。我使用它是有用的。

    【讨论】:

      【解决方案3】:

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

      //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)
      

      当我尝试触发AUTH_REQUEST时,我仍然看到Cannot read property '$http' of undefined

      【讨论】:

        【解决方案4】:

        如上所述,您应该将您的 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) })
        ...
        

        【讨论】:

          猜你喜欢
          • 2018-11-10
          • 2018-09-29
          • 2018-07-06
          • 2021-07-22
          • 2018-05-28
          • 1970-01-01
          • 2020-04-28
          • 2021-05-22
          • 2018-12-08
          相关资源
          最近更新 更多