在Vue.js中使用Axios的两种方法教程

546 阅读3分钟

Axios是一个基于承诺的HTTP客户端库,适用于浏览器和Node.js应用程序,这意味着它可以用于前端的JavaScript应用程序和后端的Node服务器。

在这篇文章中,我们将看看如何在一个简单的Vue.js应用程序中使用Axios。Vue是一个简单的前端JavaScript框架,所以这里的Axios用例将是在浏览器上。

我们将介绍:

使用Axios与Vue.js的本教程的前提条件

要跟上进度,你需要安装以下东西:

我们将使用npm作为我们的JavaScript包管理器,它包含在你安装Node时。

设置我们的Vue.js项目

我们将使用Vue CLI创建我们的项目,首先运行以下命令:

$ npm init vue@latest

这条命令提示我们如何设置我们的项目的选项。

我选择将项目命名为mice-away ,因为--你猜对了--我们要建立一个与猫有关的有趣的应用程序我们还将把它设置为使用TypeScript。

下面是我的项目配置的vue视图(我忍不住了😅 );你可以根据自己的喜好自由改变。

Axios And Vue Js Project Configuration With TypeScript Set Up

Axios通过各自名称的函数提供对不同HTTP方法的访问。例如,你可以使用 [.post(…)](https://blog.logrocket.com/understanding-axios-post-requests/) 用于POST请求,或者可以使用 [.get(…)](https://blog.logrocket.com/understanding-axios-get-requests/) 用于GET请求,等等。让我们来看看在我们的Vue项目中使用Axios进行HTTP请求的选项吧

将Axios添加到我们的Vue.js应用中

我们可以通过运行以下命令来安装Axios。

$ npm i axios

现在Axios已经安装完毕,我们来看看在我们的项目中使用它的两种方法。

在你的Vue.js组件中通过简单的导入使用Axios

你可以在你的Vue组件中使用Axios,只需在你需要进行HTTP请求的组件中导入它。这里有一个例子。

// AnimalFacts.vue


<template>
    <div class="row">
        <div class="col-md-12">
            <h3>Cat Facts</h3>
        </div>
        <div class="col-md-12">
            <ul class="list-group">
                <li v-for="(fact, index) in catFacts" :key="index" class="list-group-item">{{index + 1}}. {{fact.text}}</li>
            </ul>
        </div>
        <div class="row mt-3">
            <div class="col-md-12 text-center">
                <button @click="loadMoreFacts" class="btn btn-md btn-primary">{{ fetchingFacts ? '...' : 'Load more' }}</button>
            </div>
        </div>
    </div>
</template>
<script lang="ts">
    import { defineComponent } from 'vue'
    import axios from 'axios'
    interface AnimalFacts {
        text: string
    }
    export default defineComponent({
        name: 'AnimalFacts',
        data() {
            return {
                catFacts: [] as AnimalFacts[],
                fetchingFacts: false
            }
        },
        methods: {
            async fetchCatFacts() {
                const catFactsResponse = await axios.get<AnimalFacts[]>('https://cat-fact.herokuapp.com/facts/random?animal_type=cat&amount=5')
                this.catFacts = catFactsResponse.data
            },
            async loadMoreFacts() {
                this.fetchingFacts = true
                const catFactsResponse = await axios.get<AnimalFacts[]>('https://cat-fact.herokuapp.com/facts/random?animal_type=cat&amount=5')
                this.catFacts.push(...(catFactsResponse.data || []))

                this.fetchingFacts = false
            }
        },
        async mounted() {
            await this.fetchCatFacts()
        }
    })
</script>

在这个例子中,我们在组件中导入了Axios,并在组件的一个方法中使用它,通过调用GET 方法来获取数据并在页面上显示。你可以看到下面这个方法的结果:

Axios Vue App Result Using Import With Get Method Shown In Browser At Localhost 3000 With Title "Mice Away" And Scrollable List Of Facts Shown After Clicking Blue "Load More" Button

通过创建一个插件在我们的Vue.js项目中使用Axios

在我们的项目中使用Axios的另一个选择是创建一个插件并为我们的项目分配一个全局Axios实例。当你建立一个应用来消费一个特定的API时,这个选项很有用,它可以被配置为基本的URL。

让我们来创建我们的Axios插件!

首先,我们将通过在终端运行以下程序创建一个目录来放置我们的插件。

$ cd src/
$ mkdir plugins

接下来,我们将通过在终端运行以下程序来创建我们的Axios插件文件axios.ts

$ touch axios.ts

然后,在我们新创建的axios.ts 文件中,我们将创建一个Axios实例并使其成为全局属性。

// axios.ts

import axios from 'axios'
import type {App} from 'vue'

interface AxiosOptions {
    baseUrl?: string
    token?: string
}

export default {
    install: (app: App, options: AxiosOptions) => {
        app.config.globalProperties.$axios = axios.create({
            baseURL: options.baseUrl,
            headers: {
                Authorization: options.token ? `Bearer ${options.token}` : '',
            }
        })
    }
}

现在,我们将在main.ts 中为我们的Vue实例注册我们的插件。在注册我们的Axios插件时,我们将传入实例选项,包括我们的baseUrl

// main.ts

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'
import axios from './plugins/axios'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(axios, {
    baseUrl: 'https://cataas.com/',
})

app.mount('#app')

现在我们已经注册了Axios,我们有一个全局的Axios对象,可以通过this.$axios 。让我们在我们的组件中使用它。

// HomeView.vue

<script setup lang="ts">
</script>
<template>
  <main>
    <div class="row">
      <div class="col-md-12 text-center mb-3">
        <span @click="selectTag(tag)" v-for="(tag, index) in visibileTags" :key="index" 
          class="badge rounded-pill fs-5 me-2" :class="[tag === activeTag ? 'text-bg-primary' : 'text-bg-secondary']">
            #{{tag}}
        </span>
        <span @click="showNext()" class="badge rounded-pill text-bg-light fs-4">...</span>
      </div>
    </div>
    <div v-if="catImage" class="row">
      <div class="col-md-12 text-center">
        <img :src="catImage" class="img-fluid" height="500" width="450" :alt="activeTag ?? 'Default image'">
      </div>
    </div>
  </main>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import type {AxiosInstance} from 'axios'

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $axios: AxiosInstance
    catTags: string[]
  }
}

interface DogBreed {
  name: string
}

export default defineComponent({
  name: 'HomeView',
  data() {
    return {
      catTags: [] as string[],
      displayStart: 0,
      displayCount: 5,
      activeTag: '',
      catImage: '',
    };
  },
  computed: {
    cleanCatTags() {
      return this.catTags.filter((tag) => tag !== '').map((tag) => tag.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, ''))
    },
    totalTags() {
      return this.cleanCatTags.length
    },
    displayEnd() {
      const sliceEnd = this.displayCount + this.displayStart
      return this.totalTags > sliceEnd ? sliceEnd : this.totalTags
    },
    visibileTags() {
      return this.cleanCatTags.slice(this.displayStart, this.displayEnd)
    },
    hasNextTags() {
      return this.displayEnd < this.totalTags
    }
  },
  methods: {
    async fetchCatTags() {
      const tagsResponse = await this.$axios.get('/api/tags')
      this.catTags = tagsResponse.data
    },
    showNext() {
      this.displayStart += this.displayCount
      this.selectTag(this.cleanCatTags[this.displayStart])
    },
    selectTag(tag: string) {
      const baseUrl = 'https://cataas.com/'
      this.catImage = `${baseUrl}cat/${tag}`
      this.activeTag = tag
    },
    loadDefaultCatImage() {
      const baseUrl = 'https://cataas.com/'
      this.catImage = `${baseUrl}cat/gif`
    }
  },
  async mounted() {
    await this.fetchCatTags()
    this.loadDefaultCatImage()
  },
});
</script>

在我们的组件中,我们必须重写ComponentCustomProperties 类型,将$axios 作为一个属性。如果不这样做,我们会得到以下编译器错误:

Property $axios does not exist on type ComponentCustomProperties

为了注册$axios ,我们还必须通过运行npm i @types/axios ,导入Axios实例类型AxiosInstance ,来安装Axios类型。

在我们的HomeView 组件的fetchCatTags 方法中,我们使用this.$axios 来获取猫咪标签,通过它我们可以显示猫咪图片。

使用我们的插件实例和直接将Axios导入我们的组件之间的区别是,使用插件,我们可以为我们的Axios实例配置选项,以避免为每个请求传递某些值。

例如,使用我们的插件,我们不需要传入baseUrl ,我们对/api/tags 的请求会解析为我们配置的baseUrl

你可以通过在下面创建一个插件来看看Axios与Vue的使用结果:

Axios Vue App Resulting From Created Plugin Shown In Browser At Localhost 3000 With Title "Mice Away" And Filter Buttons With Images And Gifs Below

结论

在这篇文章中,我们尝试了两种在Vue项目中使用Axios的方法。

第一种方法是将Axios对象直接导入我们的组件中,我们用它来从一个很酷的猫咪事实API中获取猫咪事实。

我们的第二个选择是创建一个Axios插件,注入一个全局的Axios对象。我们还将Axios实例的基本URL配置为猫咪服务API,这意味着我们不必在请求中指定完整的URL。

我希望你觉得这篇文章有用。如果你有任何想法或问题,请在评论区分享!