如何在使用 vue-cli3 创建的 Vue2 项目中使用 axios

Posted

技术标签:

【中文标题】如何在使用 vue-cli3 创建的 Vue2 项目中使用 axios【英文标题】:How to use axios in Vue2 project created with vue-cli3 【发布时间】:2018-11-23 13:36:06 【问题描述】:

我使用命令vue create axe 使用vue-cli-3.0.016beta 创建了一个新的vue 项目。然后使用npm install axios --save 安装axios。在main.js文件中我导入了axios,如下图。

import Vue from 'vue'
import App from './App.vue'

import axios from 'axios'

Vue.config.productionTip = false
Vue.use(axios)

new Vue(
    render: h => h(App)
).$mount('#app')

除此之外没有任何代码更改。我仍然收到如下错误:

Unhandled promise rejection 
TypeError
​
columnNumber: 7
​
fileName: "http://localhost:8080/app.js line 1065 > eval"
​
lineNumber: 57
​
message: "parsed is undefined"
​
stack: "isURLSameOrigin@webpack-internal:///./node_modules/axios/lib/helpers/isURLSameOrigin.js:57:7\ndispatchXhrRequest@webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:109:50\nPromise@webpack-internal:///./node_modules/core-js/modules/es6.promise.js:177:7\nxhrAdapter@webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:12:10\ndispatchRequest@webpack-internal:///./node_modules/axios/lib/core/dispatchRequest.js:59:10\nrun@webpack-internal:///./node_modules/core-js/modules/es6.promise.js:75:22\nnotify/<@webpack-internal:///./node_modules/core-js/modules/es6.promise.js:92:30\nflush@webpack-internal:///./node_modules/core-js/modules/_microtask.js:18:9\n"
​
__proto__: Object  stack: "", … 

我想全局 axios 使用拦截器,因此在 main.js 中调用它。但是如果我在视图页面中使用它就没有错误!

这是一个错误还是我做错了?请帮我解决这个问题并在全球范围内使用 axios。

谢谢

【问题讨论】:

另外,我看到了这个***.com/questions/48650107/…。但我正在寻找更清洁的解决方案。 【参考方案1】:

所以我看到的错误就在这里

Vue.use(axios)

Vue.use 需要一个 vue 可安装插件。

你可以看看 vue-axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

但我强烈反对。

最好创建您自己的ApiHandler.js 文件,分别处理所有远程内容,您可以从任何地方轻松调用,包括 vue 组件和 vuex。

我的课开始了

<script>
import axios from 'axios';

class ApiHandler
  constructor(apiUrl) 
    this.axios = axios;
    this.apiUrl = apiUrl || '';  // this line allow passing a custom endpoint for testing
    this.config = 
      headers:  'Cache-Control': 'no-cache' ,  // can setup to prevent all caching
      baseURL: this.apiUrl,
    ;
  

  /**
   * @param Object payload
   * @param String payload.username
   * @param String payload.password
   */
  login( username, password ) 
    return new Promise((resolve, reject) => 
      this.axios.post('/api/login',  username: username.toLowerCase(), password , this.config)
        .then((response) => 
          if (response.code === 200 && response.body && response.body.token) 
            resolve(response.body.token);
           else 
            reject('Bad Login');
          
        )
        .catch((err) => 
          reject('internal error');
        );
    );
  

</script>

然后您可以通过...从任何地方调用它

<script>
  import ApiHandler from '../lib/ApiHandler';
  const apiRequest = new ApiRequest();

  // and then anywhere in the script
  let payload = 
    username:'someuser',
    password:'somepassword',
  ;
  apiRequest.login(payload)
    .then(()=>
      // yay - I'm logged in
    )
    .catch(err => 
      // oh oh, display error
    )
</script>

这为您提供了更大的灵活性,并允许您分离远程操作,并允许将第一站响应处理与您的组件分开,从而实现更多的可重用性。

【讨论】:

我了解丹尼尔。谢谢回答。但是如果项目有点大,恐怕ApiHandler文件太大而无法处理? 是的,但是你可以将文件分成多个文件。ApiHandler 将拥有主要的 axios 引用并导入其他文件,在某些方面类似于 vuex 存储的组合方式。 好的!就可以了...谢谢丹尼尔...我会选择您的答案,请稍等几天,看看是否有人可以提供更多信息。干杯!【参考方案2】:

而不是

Vue.use(axios);

你应该

Vue.prototype.$axios = axios;

那么你就可以全局使用了

login() 
    this.$axios.post('<host>/api/login', data)
        .then((res) =>  // dosomething )
        .catch((err) =>  // dosomething );    

如果你想用axios添加全局拦截器,可以

// Add a request interceptor
axios.interceptors.request.use(function (config) 
    // Do something before request is sent
    return config;
, function (error) 
    // Do something with request error
    return Promise.reject(error);
);

// Add a response interceptor
axios.interceptors.response.use(function (response) 
    // Do something with response data
    return response;
, function (error) 
    // Do something with response error
    return Promise.reject(error);
);

// and
Vue.prototype.$axios = axios;

【讨论】:

以上是关于如何在使用 vue-cli3 创建的 Vue2 项目中使用 axios的主要内容,如果未能解决你的问题,请参考以下文章

vue-cli 初始化创建 vue2.9.6 项目

vue-cli 初始化创建 vue2.9.6 项目

vue2.0和3.0区别

Vue2.6.10(Vue-cli4)项目打包性能优化实践

使用 vue-cli 创建的 Vue 2 项目的 npm 更新失败

vue2.0 vue-cli+webpack使用less和sass的说明