引用 ts-axios 库

在 TS 项目中引用

我们借助于 vue-cli 脚手架创建一个 TypeScript 的 Vue 项目,然后我们把 Vue 官网上一段使用 axios 发请求的 demo 代码抄过来。

我们需要先执行 npm install ts-axios-new 安装 ts-axios 库。

HelloWorld.vue

  1. <template>
  2. <div class="hello">
  3. <p>
  4. Ask a yes/no question:
  5. <input v-model="question">
  6. </p>
  7. <p>{{ answer }}</p>
  8. </div>
  9. </template>
  10. <script lang="ts">
  11. import Vue from 'vue'
  12. import _ from 'lodash'
  13. import axios from 'ts-axios-new'
  14. export default Vue.extend({
  15. name: 'HelloWorld',
  16. data () {
  17. return {
  18. question: '',
  19. answer: 'I cannot give you an answer until you ask a question!'
  20. }
  21. },
  22. created () {
  23. this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  24. },
  25. methods: {
  26. debouncedGetAnswer () {
  27. // do nothing
  28. },
  29. getAnswer () {
  30. if (this.question.indexOf('?') === -1) {
  31. this.answer = 'Questions usually contain a question mark. -)'
  32. return
  33. }
  34. this.answer = 'Thinking...'
  35. const instance = axios.create()
  36. instance.interceptors.request.use((config) => {
  37. config.params = {
  38. _t: +new Date()
  39. }
  40. return config
  41. })
  42. instance.get('https://yesno.wtf/api')
  43. .then((response) => {
  44. this.answer = _.capitalize(response.data.answer)
  45. })
  46. .catch((error) => {
  47. this.answer = 'Error! Could not reach the API. ' + error
  48. })
  49. }
  50. },
  51. watch: {
  52. question: function (newQuestion: string, oldQuestion: string) {
  53. this.answer = 'Waiting for you to stop typing...'
  54. this.debouncedGetAnswer()
  55. }
  56. }
  57. })
  58. </script>
  59. <!-- Add "scoped" attribute to limit CSS to this component only -->
  60. <style scoped>
  61. h3 {
  62. margin: 40px 0 0;
  63. }
  64. ul {
  65. list-style-type: none;
  66. padding: 0;
  67. }
  68. li {
  69. display: inline-block;
  70. margin: 0 10px;
  71. }
  72. a {
  73. color: #42b983;
  74. }
  75. </style>

这段代码主要是提供了一个 input 输入框,绑定了 question 变量,当我们输入的时候,会触发 question 的变化,执行 watch question 中的逻辑,执行 this.debouncedGetAnswer 方法,实际上就是 debounce 执行了 getAnswer 方法,发送请求。

我们通过 import axios from 'ts-axios-new' 去加载 ts-axios 库,实际上就是引入了 node_modules/ts-axios-new/dist/axios.es5.js,因为 ts-axios-newpackage.json 文件中配置的 module 字段是 dist/axios.es5.js,在 webpack 中优先 import 优先会找 module 字段,其次是 main 字段。

小技巧:当我们引入某个库运行时出现问题时候,我们就可以调试 node_modules 中对应引入的代码。

注意我们这里先使用了 axios.create() 方法创建了一个 instance,然后添加了一个请求拦截器,会在每次发送请求前,添加了一个 _t 参数,值为时间戳。然后执行 instance.get 发送一个请求。

我们可以看到整个 demo 是可以正常运行的,并且没有任何类型相关的问题,说明我们的库打包后的代码和类型声明文件都是没有问题的。

在 JS 项目中引用

我们编写的 TS 库仍然可以被纯 JS 的项目引用,这次我们来修改《Vue.js2.5+cube-ui重构饿了么App》课程的代码,把之前对 axios 的引用改成对 ts-axios-new 的引用。课程源码是开源的,所以没购买课程的小伙伴也可以去 GitHub 下载。

我们需要先执行 npm install ts-axios-new 安装 ts-axios 库,然后修改代码。

api/helpers.js

  1. import axios from 'ts-axios-new'
  2. const urlMap = {
  3. development: '/',
  4. production: 'http://ustbhuangyi.com/sell/'
  5. }
  6. const baseUrl = urlMap[process.env.NODE_ENV]
  7. const ERR_OK = 0
  8. export function get(url) {
  9. return function(params = {}) {
  10. return axios.get(baseUrl + url, {
  11. params
  12. }).then((res) => {
  13. const {errno, data} = res.data
  14. if (errno === ERR_OK) {
  15. return data
  16. }
  17. }).catch((e) => {
  18. })
  19. }
  20. }

只需要把 import axios from 'axios' 修改为 import axios from 'ts-axios-new' 即可。

接着运行项目,我们发现项目可以成功运行,因为我们实现了axios 在浏览器端的所有功能,所以可以放心的做替换。

至此,我们就完成了 ts-axios 库的开发、测试、编译、发布和引用。课程到这里也就告一段落了,下一章我们会对整个课程做总结与展望。