Vue3——网络框架Axios的应用

网络框架Axios的应用

1、使用vue-axios请求天气数据

1.1、使用互联网上免费的数据服务

互联网上众多的第三方API接口为开发个人小工具应用提供了极大的便利,同时也为编程技能的学习和测试提供了优秀的平台。​"聚合数据"作为这些服务中的佼佼者,以其出色的数据服务在众多领域中突显其优势。它不仅提供了丰富多样的数据接口服务,而且其数据的广度和深度都非常令人印象深刻。利用"聚合数据"提供的服务,我们可以轻松访问并整合各类数据,进而推动个人或商业项目的发展。其官方网址为:

https://www.juhe.cn

要使用"聚合数据"提供的接口服务,首先需要在"聚合数据"网站上注册成为会员。注册过程完全免费,且提供的免费API接口服务足以满足我们后续学习和使用的需求。注册会员的网址为:
https://www.juhe.cn/register

在注册页面,我们需要填写一些基本的信息,可以选择使用电子邮箱或手机号注册。使用电子邮箱注册时的页面如图所示。

注意,在注册前务必阅读《聚合用户服务协议》与《聚合隐私协议》​,并且填写真实有效的邮箱地址,要真正完成注册过程,需要登录邮箱进行验证。

注册成功后,还需要通过实名认证才能使用"聚合数据"提供的接口服务,在个人中心的实名认证页面,根据提示提供对应的身份认证信息,等待审核通过即可。

下面我们查找一款感兴趣的API接口服务,如图所示。

以天气预报服务为例,申请使用后,可以在"个人中心"→"数据中心"→"我的API"栏目中看到此数据服务,需要记录其中的请求Key,后面我们在调用此接口服务时需要使用到,如图所示。

之后,进入"天气预报"服务的详情页,在详情页会提供此接口服务的接口地址、请求方式,请求参数说明和返回参数说明等信息,我们需要根据这些信息来进行应用的开发,如图所示。

现在,尝试使用终端进行接口的请求测试,在终端输入如下指令:

shell 复制代码
curl -k -i "https://apis.juhe.cn/simpleWeather/query?key=key&city=苏州"

注意,其中的参数key对应的值为我们前面记录的应用的Key值,city对应的是要查询的城市的名称,返回如下:

json 复制代码
{
  "reason": "查询成功!",
  "result": {
    "city": "苏州",
    "realtime": {
      "temperature": "18",
      "humidity": "50",
      "info": "晴",
      "wid": "00",
      "direct": "西风",
      "power": "4-5级",
      "aqi": "43"
    },
    "future": [
      {
        "date": "2026-04-30",
        "temperature": "11\/19℃",
        "weather": "晴转多云",
        "wid": { "day": "00", "night": "01" },
        "direct": "西北风转西南风"
      },
      {
        "date": "2026-05-01",
        "temperature": "14\/23℃",
        "weather": "阴",
        "wid": { "day": "02", "night": "02" },
        "direct": "西南风转东南风"
      },
      {
        "date": "2026-05-02",
        "temperature": "17\/26℃",
        "weather": "阴转小雨",
        "wid": { "day": "02", "night": "07" },
        "direct": "南风转西风"
      },
      {
        "date": "2026-05-03",
        "temperature": "14\/24℃",
        "weather": "阴",
        "wid": { "day": "02", "night": "02" },
        "direct": "西北风转西风"
      },
      {
        "date": "2026-05-04",
        "temperature": "14\/27℃",
        "weather": "多云",
        "wid": { "day": "01", "night": "01" },
        "direct": "西南风转东北风"
      }
    ]
  },
  "error_code": 0
}

1.2、 使用vue-axios进行数据请求

Axios本身是一个基于promise的HTTP客户端工具,vue-axios是针对Vue对Axios进行了一层简单的包装。在Vue应用中,使用其进行网络数据的请求非常简单。

首先,在项目工程下执行如下指令进行vue-axios模块的安装:

shell 复制代码
npm install --save axios vue-axios

安装完成后,可以检查一下package.json文件中是否已经添加了vue-axios的依赖。还记得我们使用Element Plus框架时的步骤吗,使用vue-axios与其类似,首先需要在main.js文件中对其进行导入和注册,代码如下:

js 复制代码
     // 导入vue-axios模块
     import VueAxios from 'vue-axios'
     import axios from 'axios';
     // 导入自定义的根组件
     import App from './App.vue'
     // 挂载根组件
     const app = createApp(App)
     // 注册axios
     app.use(VueAxios, axios)
     app.mount('#app')

注意,要在导入我们自定义的组件之前进行vue-axios模块的导入。之后,我们可以以任意一个组件为例,在其setup中编写如下代码进行请求测试:

js 复制代码
<script setup>
  import { onMounted, getCurrentInstance } from 'vue'
  //获取挂载到应用中心的Axios实例
  let axios = getCurrentInstance().appContext.app.axios
  //组件挂载时执行
  onMounted(()=>{
    let api = "https://apis.juhe.cn/simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=长春"
    //发起Get请求
    axios.get(api).then((response)=>{
      //请求结果打印出来
      console.log(response)
    })
  })
</script>

运行代码,打开浏览器的控制台,你会发现请求并没有按照我们的预期方式成功完成,控制台会输出如下信息:

js 复制代码
Access to XMLHttpRequest at 'https://apis.juhe.cn/simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=%E9%95%BF%E6%98%A5' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

出现此问题的原因在于产生了跨域请求,在Vite创建的项目中更改全局配置即可解决此问题。使用Vite创建的工程默认会在根目录下生成一个名为vite.config.js的文件(如果不存在,直接创建即可)​,在其中编写如下配置项:

js 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
  //默认
  plugins: [vue()],
  //配置服务器
  server: {
    proxy: {
      //对以myApi开头的请求进行代理
      '/myApi': {
        //将请求目标指定到接口服务地址
        target: 'http://apis.juhe.cn/',
        //设置允许跨域
        changeOrigin: true,
        //重写路径,将/myApi即之前的内容清楚
        rewrite: (path) => path.replace(/^\/myApi/, '')
      }
    }
  }
})

修改请求数据的测试代码如下:

js 复制代码
<script setup>
  import { onMounted, getCurrentInstance } from 'vue'
  //获取挂载到应用中心的Axios实例
  let axios = getCurrentInstance().appContext.app.axios
  //组件挂载时执行
  onMounted(()=>{
    let city = '长春'
    let api = `simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=${city}`
    //发起Get请求
    axios.get('/myApi' + api).then((response)=>{
      //请求结果打印出来
      console.log(response)
    })
  })
</script>

如以上代码所示,我们将请求的API接口前的地址强制替换成了字符串"/myApi"​,这样请求就能进入我们配置的代理逻辑中,实现跨域请求。还有一点需要注意,我们要请求的城市是上海,真正发起请求时,需要对城市进行URI编码。重新运行Vue项目,在浏览器控制台可以看到,我们已经能够正常访问接口服务了,如图所示。

通过实例代码可以看到,使用vue-axios进行数据的请求非常简单,在组件内部直接使用axios.get方法即可发起GET请求。当然,也可以使用axios.post方法来发起POST请求,此方法会返回Pormise对象,后续可以获取到请求成功后的数据或失败的原因。

2、Axios实用功能介绍

2.1、通过配置的方式进行数据请求

Axios中提供了许多快捷的请求方法,在11.1节中,我们编写的请求示例代码中使用的就是Axios提供的快捷方法。如果要直接进行GET请求,使用如下方法即可:

js 复制代码
axios.get(url[, config])

其中,url参数是要请求的接口;config参数是选填的,用来配置请求的额外选项。与此方法类似,Axios中还提供了下面的常用快捷方法:

js 复制代码
     // 快捷发起POST请求,data设置请求的参数
     axios.post(url[, data[, config]])
     // 快捷发起DELETE请求
     axios.delete(url[, config])
     // 快捷发起HEAD请求
     axios.head(url[, config])
     // 快捷发起OPTIONS请求
     axios.options(url[, config])
     // 快捷发起PUT请求
     axios.put(url[, data[, config]])
     // 快捷发起PATCH请求
     axios.patch(url[, data[, config]])

除使用这些快捷方法外,我们也可以完全通过自己的配置来进行数据请求,示例代码如下:

js 复制代码
<script setup>
  import { onMounted, getCurrentInstance } from 'vue'
  //获取挂载到应用中心的Axios实例
  let axios = getCurrentInstance().appContext.app.axios
  //组件挂载时执行
  onMounted(()=>{
    let city = '长春'
    let api = `simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=${city}`
    //发起Get请求
    axios({
      method: 'get',
      url: '/myApi' + api,
    }).then((response)=>{
      console.log(response.data)
    }) 
  })
</script>

通过这种配置的方式进行的数据请求效果与使用快捷方法一致。注意,在配置时必须设置请求的method方法。

通常,在同一个项目中,使用到的请求很多配置都是相同的,对于这种情况,可以创建一个新的Axios请求实例,之后所有的请求都使用这个实例来发起,实例本身的配置会与快捷方法的配置合并,这样既能够复用大多数相似的配置,又可以实现某些请求的定制化,示例代码如下:

js 复制代码
<script setup>
  import { onMounted, getCurrentInstance } from 'vue'
  //获取挂载到应用中心的Axios实例
  let axios = getCurrentInstance().appContext.app.axios
  //统一配置URL前缀、超时时间和自定义的header
  const instance = axios.create({
    baseURL: '/myApi',
    timeout: 1000,
    headers: {'X-Custom-Header': 'custom'}
  })
  //组件挂载时执行
  onMounted(()=>{
    let city = '长春'
    let api = `simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=${city}`
    //发起Get请求
    instance.get(api).then((response)=>{
      console.log(response.data)
    })
  })
</script>

如果需要让某些配置作用于所有请求,即需要重设Axios的默认配置,则可以使用Axios的defaults属性进行配置,例如:

js 复制代码
<script setup>
  import { onMounted, getCurrentInstance } from 'vue'
  //获取挂载到应用中心的Axios实例
  let axios = getCurrentInstance().appContext.app.axios
  axios.defaults.baseURL = '/myApi' 
  //组件挂载时执行
  onMounted(()=>{
    let city = '长春'
    let api = `simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=${city}`
    //发起Get请求
    axios.get(api).then((response)=>{
      console.log(response.data)
    })
  })
</script>

在对请求配置进行合并时,会按照一定的优先级进行选择,优先级排序如下:

复制代码
axios默认配置 < defaults属性配置 < 请求时的config参数配置

2.2、请求的配置与响应数据结构

在Axios中,无论我们使用配置的方式进行数据请求还是使用快捷方法进行数据请求,都可以传一个配置对象来对请求进行配置,此配置对象可配置的参数非常丰富,列举如表所示。

参数 意义
url 设置请求的接口URL 字符串
method 设置请求方法 字符串,默认为'get'
baseURL 设置请求的接口前缀,会拼接在URL之前 字符串
transformRequest 用来拦截请求,在发起请求前进行数据的修改 函数,此函数会传入(data,headers)两个参数,将修改后的data进行返回即可
transformResponse 用来拦截请求回执,在收到请求回执后调用 函数,此函数会传入(data)作为参数,将修改后的data进行返回即可
headers 自定义请求头数 对象
paramsSerializer 自定义参数的序列化方法 函数
data 设置请求体要发送的数据 字符、对象、数组等
timeout 设置请求的超时时间 数值,单位为毫秒,若设置为0,则永不超时
withCredentials 设置跨域请求时是否需要凭证 布尔值
auth 设置用户信息 对象
responseType 设置响应数据的数据类型 字符串,默认为'json
responseEncoding 设置响应数据的编码方式 字符串,默认为'utf8'
maxContentLength 设置允许响应的最大字节数 数值
maxBodyLength 设置请求内容的最大字节数 数值
validateStatus 自定义请求结束的状态,是成功或失败 函数,会传入请求到的(status)状态码作为参数,需要返回布尔值决定请求是否成功

通过表列出的配置属性,基本可以满足各种场景下的数据请求需求。当一个请求被发出后,Axios会返回一个Promise对象,通过此Promise对象可以异步地等待数据返回,Axios返回的数据是一个包装好的对象,其中包装的属性列举如表所示。

参数 意义
Data 接口服务返回的响应数据 对象
status 接口服务返回的HTTP状态码 数值
statusText 接口服务返回的HTTP状态信息 字符串
headers 响应头数据 对象
config Axios设置的请求配置信息 对象
request 请求实例 对象

2.3、拦截器的使用

拦截器的功能在于允许开发者在请求发起前或请求完成后进行拦截,从而在这些时机添加一些定制化的逻辑。举一个很简单的例子,在请求发送前,需要激活页面的Loading特效,在请求完成后移除Loading特效,同时,如果请求的结果是异常的,可能还需要进行弹窗提示,而这些逻辑对于项目中的大部分请求来说可能都是通用的,这时就可以使用拦截器。

要在请求的开始阶段进行拦截,示例代码如下:

js 复制代码
  axios.interceptors.request.use((config)=>{
    alert('请求将要开始')
    return config
  }, (error)=>{
    alert('请求出现错误')
    return Promise.reject(error)
  })

运行上述代码,在请求开始前会有弹窗提示。

我们也可以在请求完成后进行拦截,示例代码如下:

js 复制代码
  axios.interceptors.response.use((response)=>{
    alert(response.status)
    return response
  }, (error)=>{
    return Promise.reject(error)
  })

在拦截器中,我们也可以对响应数据进行修改,将修改后的数据返回到请求调用处使用。

注意,请求拦截器的添加是和Axios请求实例绑定的,后续此实例发起的请求都会被拦截器拦截,但是我们可以使用如下方式在不需要拦截器的时候将其移除:

js 复制代码
  let i = axios.interceptors.request.use((config)=>{
    alert('请求将要开始')
    return config
  }, (error)=>{
    alert('请求出现错误')
    return Promise.reject(error)
  })
  //移除烂机器
  axios.interceptors.request.eject(i)

3、天气预报应用示例

利用聚合数据提供的天气预报接口服务,尝试开发一款天气预报网页应用。如果之前观察过天气预报接口返回的数据结构,你会发现它包含两部分数据:一部分是当前的天气信息,另一部分是未来几天的天气预报。在设计页面时,我们同样可以将其划分为两个模块,分别用于展示当日的天气状况和未来几日的天气预报。

html 复制代码
<template>
    <el-container class="container">
        <el-header>
            <el-input v-model="city" placeholder="请输入" class="input">
                <template #prepend>城市名:</template>
            </el-input>
        </el-header>
        <el-main class="main">
            <div class="today">
                今天:
                <span>{{ todayData.weather ?? plc }}{{ todayData.temperature ?? plc }}</span>
                <span style="margin-left:20px;">{{ todayData.direct ?? plc }}</span>
                <span style="margin-left: 100px;">{{ todayData.date }}</span>
            </div>
            <div class="real">
                <span class="temp">{{ realtime.temperature ?? plc }}°</span>
                <span class="realInfo">{{ realtime.info ?? plc }}</span>
                <span class="realInfo" style="margin-left: 20px;">{{ realtime.direct ?? plc }}</span>
                <span class="realInfo" style="margin-left: 20px;">{{ realtime.power ??plc }}</span>
            </div>
            <div class="real">
                <span class="realInfo">空气质量:{{ realtime.aqi ?? plc }}</span>
                <span class="realInfo" style="margin-left: 20px;">湿度:{{ realtime.humidity ?? plc }}</span>
            </div>
            <div class="future">
                <div class="header">5日天气预报</div>
                <el-table :data="futureData" style="margin-top: 30px;">
                    <el-table-column prop="date" label="日期"></el-table-column>
                    <el-table-column prop="temperature" label="湿度"></el-table-column>
                    <el-table-column prop="weather" label="天气"></el-table-column>
                    <el-table-column prop="direct" label="风向"></el-table-column>
                </el-table>
            </div>
        </el-main>
    </el-container>
</template>

<script setup>
    import {onMounted, getCurrentInstance, ref, watch} from 'vue'

    const city = ref('长春') 
    const weatherData = ref({})
    const todayData = ref({})
    const plc = ref('暂无数据')
    const realtime = ref({})
    const futureData = ref([])
    const requestData = ()=>{
        let api = `simpleWeather/query?key=db5d47318e99d65cb10e16d5a0d96860&city=${city.value}`
        axios.get(api).then((response)=>{
            weatherData.value = response.data
            todayData.value = weatherData.value.result.future[0]
            realtime.value = weatherData.value.result.realtime
            futureData.value = weatherData.value.result.future
        })
    }
    let axios = getCurrentInstance().appContext.app.axios

    //组件挂载时,进行默认数据的初始化
    onMounted(()=>{
        axios.defaults.baseURL = '/myApi'
        requestData()
    })

    //当用户输入的城市发生变化后,调用接口进行数据请求
    watch(city, ()=>{
        requestData()
    })
</script>

<style scoped>
    .container {
        background: linear-gradient(rgb(13, 104, 188), rgb(54, 131, 195));
        text-align: left;
    }
    .input {
        width: 180px;
        margin-top: 20px;
    }
    .today {
        font-size: 20px;
        color: white;
        padding: 10px;
    }
    .temp {
        font-size: 39px;
        color: white;
    }
    .real {
        padding: 10px;
    }
    .realInfo {
        color: white;
    }
    .future {
        margin-top: 40px;
    }
    .header {
        color: white;
        font-size: 27px;
    }
</style>
相关推荐
一粒黑子13 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
IT枫斗者13 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
Beginner x_u14 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
我叫汪枫15 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch15 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI15 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_00115 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
念23415 小时前
f5 shape分析
开发语言·javascript·ecmascript
難釋懷15 小时前
Vue混入
前端·javascript·vue.js