Axios的基本知识点以及vue的开发工程(基于大事件)详细解释

什么是Axios?

Axios 是一个专门用于发送 HTTP 请求的 JavaScript 库,常用于前端项目中和后端服务器交互。

用简单的话来说

你可以把 Axios 想象成一个"快递小哥"。它负责在你写的代码和服务器之间"递送"信息。比如,你写了一个"下单"请求,Axios 就像快递员一样,把这个请求带到服务器,服务器处理后再把结果送回给你。这样你就能从服务器那里获取数据或将数据发给服务器。

为什么要用 Axios?

简单易用:相比原生的 fetch 和 XMLHttpRequest,用 Axios 写请求代码更简单,写法更清晰。

自动处理 JSON:它自动把数据转成 JSON 格式,不用你自己转换,省心省力。

处理错误方便:它内置了错误处理,你可以轻松捕捉请求失败的原因。

支持更多功能:像请求拦截、取消请求等高级功能,能让你的项目更灵活。

使用 Axios 是通过配置请求的 URL 和 参数,然后由 Axios 去发出请求并等待后端的响应。你只需要写好调用代码,Axios 就会帮助你发出请求,等待后端返回的数据,然后处理这个数据,整个过程会比手动写更简单。

如何使用Axios?

Axios的写法

第一种方式

引入 Axios 的 JavaScript 文件: 在 HTML 文件中通过<script>标签引入 Axios 的 JavaScript 文件,如图所示使用外部链接 https://unpkg.com/axios/dist/axios.min.js,这样就可以在网页中使用 Axios。

发送请求并处理响应:method: 'GET':指定请求的方式为 GET 请求。
url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/list':指定请求的 URL。

.then(result => { console.log(result.data); }):请求成功时的回调函数,result.data 用于访问返回的数据。

.catch(err => { alert(err); }):请求失败时的回调函数,使用 alert(err) 显示错误信息。

第二种方式

基本用法

发送 GET 请求

javascript 复制代码
axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data); // 处理响应数据
  })
  .catch(error => {
    console.log(error); // 处理错误
  });

发送 POST 请求

javascript 复制代码
axios.post('https://api.example.com/data', {
    name: 'John',
    age: 30
  })
  .then(response => {
    console.log(response.data); // 处理响应数据
  })
  .catch(error => {
    console.log(error); // 处理错误
  });

响应对象

Axios 请求的响应数据包含以下主要字段:

data:返回的数据内容,通常是服务器响应的主体数据。
status:HTTP 响应状态码 ( 200, 404)。
statusText:HTTP 响应状态的文本描述("OK")。
headers:响应头信息。
config:请求配置对象。
request:发起请求的原始请求对象。

javascript 复制代码
axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);  // 返回的数据
    console.log(response.status); // 响应状态码
    console.log(response.headers); // 响应头
  })
  .catch(error => {
    console.error(error.response); // 错误响应对象
  });

vue的API风格

Vue 的 API 风格主要有两种:选项式 API(Options API)组合式 API(Composition API)。这两种风格各有特点,适用于不同的使用场景:

1. 选项式 API (Options API)

选项式 API 是 Vue2 中的传统风格,它通过配置对象的方式将逻辑分散到不同的选项(如 datamethodscomputed 等)中。适合组件逻辑简单、容易分离的场景。

  • 常用选项
  • data:定义组件的响应式数据。
  • methods:定义组件的方法。
  • computed:定义计算属性。
  • watch:监视响应式数据的变化。
  • propsemits:用于定义组件的输入和输出。
  • 示例:
javascript 复制代码
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};

2. 组合式 API (Composition API)

组合式 API 是在 Vue 3 中引入的新风格,通过函数(如 setup)将逻辑聚合到一起,提升代码复用性和灵活性。适合复杂逻辑的场景,尤其是在组件需要多个逻辑模块时。

  • 特点
  • 提供更高的灵活性和可复用性。
  • 更适合复杂逻辑,逻辑更集中、模块化。
  • 支持直接导入 Vue 的核心 API,如 refcomputedwatch
  • 核心 API
  • ref:定义响应式变量。
  • reactive:定义响应式对象。
  • computed:创建计算属性。
  • watchwatchEffect:监听响应式数据的变化。
  • provideinject:在组件间提供和注入数据。示例:
javascript 复制代码
import { ref } from 'vue';

export default {
 setup() {
   const count = ref(0);
   const increment = () => {
     count.value++;
   };
   return {
     count,
     increment
   };
 }
};

如何解决跨域请求

1. 代理配置 (server.proxy)

server.proxy 中配置了代理,以解决前端和后端之间的跨域问题。

匹配路径:
'/api' 用于匹配所有以 /api 开头的请求路径,这些请求将被代理转发。

目标服务器:
target: 'http://localhost:8080' 指定了目标服务器的地址,所有匹配/api的请求会被转发到 http://localhost:8080,即后端服务器的地址。

改变源 (changeOrigin: true):

代理请求时会伪装请求的来源,使请求看起来是从目标服务器发出的,从而绕过浏览器的同源策略。

路径重写 (rewrite):
rewrite: (path) => path.replace(/^\/api/, '') 会将请求路径中的 /api 部分移除,以便后端服务器能够正确处理请求路径。

javascript 复制代码
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server:{
    proxy:{
      '/api':{
        // 获取路径中包含了/api的请求
        target:'http://localhost:8080',// 后台服务器所在的源
        changeOrigin:true,//修改源
        rewrite:(path)=>path.replace(/^\/api/,'')
        // /api替换为空字符串
      }
    }
  }
})
2. 整体流程

当前端向 /api/... 发起请求时(在request.js中定义过baseURL = '/api'),代理会将请求转发到 http://localhost:8080/...

通过 changeOrigin: true,修改了请求的来源信息,从而避免了跨域限制。

使用 rewrite 重写路径,使得请求路径符合后端服务器的需求。

对于api接口的优化

  1. 发现问题 :在项目中,每次 API 请求都需要写 .then.catch 来处理响应和错误,导致代码重复,维护困难。
  2. 解决方案 :将 Axios 请求和响应的逻辑提取到拦截器中,在 request.js 中创建一个 Axios 实例,配置统一的请求和响应拦截器。
javascript 复制代码
// request.js
//定制请求的实例
// 定制请求的实例
import axios from "axios";
const baseURL = 'http://localhost:8080';
const instance = axios.create({baseURL})

// 添加响应拦截器
instance.interceptors.response.use(
    result=>{
        return result.data;
    },error => {
        alert("服务异常");
        return Promise.reject(error); // 把异步的状态转化为失败的状态
    }
)

export  default  instance;
  1. 使用封装的 Axios 实例 :在其他文件中(如 article.js)直接使用 request 实例发起请求,不再需要手动写 .then.catch
javascript 复制代码
// article.js
import request from '@/util/request';

export function articleGetAllService() {
  // 直接返回请求结果,无需写 .then 和 .catch
  return request.get('/article/getAll');
}

export function articleSearchService(conditions) {
  return request.get('/article/search', { params: conditions });
}
  1. 调用 API :在组件或其他业务逻辑中调用 articleGetAllServicearticleSearchService,简化代码逻辑。
javascript 复制代码
<script setup>
import {ref,onMounted} from "vue";
// 导入axios,npm install axios
import axios from "axios";
import {articleGetAllService,articleSearchService} from '@/api/article.js';
  const articleList = ref([]);
  // 同步获取articleGetAllservice的返回结果async await
  const getAllArticle = async function (){
   let data = await articleGetAllService();
    articleList.value = data;
  }
  getAllArticle();
  // 定义响应式数据
  const searchConditions = ref({
    category:'',
    state:''
  });

  const search = async function (){
    let data = await articleSearchService({...searchConditions.value});
    articleList.value = data;
  }
</script>

<template>
  <div>

    文章分类: <input type="text" v-model="searchConditions.category">

    发布状态: <input type="text" v-model="searchConditions.state">

    <button @click="search">搜索</button>

    <br/>
    <br/>
    <table border="1 solid" colspa="0" cellspacing="0">
      <tr>
        <th>文章标题</th>
        <th>分类</th>
        <th>发表时间</th>
        <th>状态</th>
        <th>操作</th>
      </tr>
      <tr v-for="(article,index) in articleList">
        <td>{{ article.title }}</td>
        <td>{{ article.category }}</td>
        <td>{{ article.time }}</td>
        <td>{{ article.state }}</td>
        <td>
          <button>编辑</button>
          <button>删除</button>
        </td>
      </tr>

    </table>
  </div>
</template>

<style scoped>

</style>

效果 :通过拦截器的方式简化了请求代码,不再需要在每次调用时写 .then.catch,请求和错误处理逻辑集中管理,代码更简洁,维护更容易。

对于实际开发中登录和注册的页面的拦截器

左侧代码

左侧的代码示例展示了 login register 两个函数的写法,每个函数都需要手动检查 result.code 是否为 0 来判断操作是否成功,并根据状态码执行相应的逻辑,比如提示"登录成功"或"注册成功",否则显示"登录失败"或"注册失败"。

这种方法的问题在于,如果多个接口都需要类似的状态码判断逻辑,会导致代码重复,不利于维护。

右侧代码

右侧的代码示例展示了使用 Axios 响应拦截器来简化这种重复的判断逻辑:

添加响应拦截器:

通过 instance.interceptors.response.use() 方法,可以拦截所有响应,在拦截器中统一处理业务逻辑。

状态码检查:

拦截器中首先判断 result.data.code 是否为 0。如果为 0,则代表操作成功,返回数据 result.data

错误处理:

如果状态码不为 0,则直接在拦截器中提示错误信息(result.data.message)或"服务异常",并通过Promise.reject返回错误,使得在调用的地方可以专注于具体的数据处理逻辑。

全局异常处理:

拦截器中还捕获了网络异常或其他错误,显示"服务异常"并拒绝 Promise。

拦截器
javascript 复制代码
//定制请求的实例

import { ElMessage } from 'element-plus'
//导入axios  npm install axios
import axios from 'axios';
//定义一个变量,记录公共的前缀  ,  baseURL
// const baseURL = 'http://localhost:8080';
const baseURL = '/api';
const instance = axios.create({baseURL})


//添加响应拦截器
instance.interceptors.response.use(
    result=>{
        // 判断业务状态码
        if(result.data.code === 0){
            // 操作成功
            return result.data;
        }
        // 操作失败
        // alert(result.data.message ? result.data.message : '服务异常')
        ElMessage.error(result.data.message ? result.data.message : '服务异常')
        // 把异步操作的状态转换为失败
        return Promise.reject(result.data)
    },
    err=>{
        alert('服务异常');
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;
Login.vue的代码(运用拦截器以及校验)
javascript 复制代码
<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'

import { ElMessage } from 'element-plus'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)
// 定义数据模型
const registerData = ref({
  username:'',
  password:'',
  rePassword:''
})
// 校验密码的函数
const checkRepasswrd=(rule,value,callback)=>{
  if(value === ''){
    callback(new Error('请再次确认密码'))
  }else if(value !== registerData.value.password){
    callback(new Error('请确保两次输入的密码一样'))
  }else callback();
}

// 定义表单校验规则
const rules={
  username:[{required:true,message:'请输入用户名',trigger:'blur'},
    {min:5,max:16,message: '长度为5-16位的非空字符',trigger: 'blur'}
  ],

  password:[{required:true,message:'请输入密码',trigger:'blur'},
    {min:5,max:16,message: '长度为5-16位的非空字符',trigger: 'blur'}],
  rePassword:[{validator:checkRepasswrd,trigger:'blur'}]
}

import {userRegisterService,userLoginService} from '@/api/user.js'
const register = async () => {
    let result = await userRegisterService(registerData.value);
    //   if (result.code === 0) {
    //     alert(result.message ? result.message : '注册成功');
    //   } else {
    //     alert(result.message ? result.message : '注册失败');
    //   }
    // alert(result.message ? result.message : '注册成功')
  ElMessage.success(result.message ? result.message : '注册成功')
};


// 登录页面的绑定数据,复用注册表单的数据
// 表单数据校验

// 登录函数

const login = async ()=>{
  // 调用接口,完成登录
  let result = await userLoginService(registerData.value)
  // if(result.code === 0){
  //   alert(result.message ? result.message : '登录成功')
  // }else alert('登录失败')
  // alert(result.message ? result.message : '登录成功')
  ElMessage.success(result.message ? result.message : '登录成功')
}

// 定义函数用来清空模型的数据
const clearRegisterData = ()=>{
  registerData.value={
    username: '',
    password: '',
    rePassword: '',
  }
}
</script>

<template>
  <el-row class="login-page">
    <el-col :span="12" class="bg"></el-col>
    <el-col :span="6" :offset="3" class="form">
      <!-- 注册表单 -->
      <el-form ref="form" size="large" autocomplete="off" v-if="isRegister"
               :model="registerData" :rules="rules">
        <el-form-item>
          <h1>注册</h1>
        </el-form-item>
        <el-form-item prop="username">
          <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username" ></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
        </el-form-item>
        <el-form-item prop="rePassword">
          <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>
        </el-form-item>
        <!-- 注册按钮 -->
        <el-form-item>
          <el-button class="button" type="primary" auto-insert-space @click="register">
            注册
          </el-button>
        </el-form-item>
        <el-form-item class="flex">
          <el-link type="info" :underline="false" @click="isRegister = false;clearRegisterData()">
            ← 返回
          </el-link>
        </el-form-item>
      </el-form>
      <!-- 登录表单 -->
      <el-form ref="form" size="large" autocomplete="off" v-else :model="registerData" rules="rules">
        <el-form-item>
          <h1>登录</h1>
        </el-form-item>
        <el-form-item prop="username">
          <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
        </el-form-item>
        <el-form-item class="flex">
          <div class="flex">
            <el-checkbox>记住我</el-checkbox>
            <el-link type="primary" :underline="false">忘记密码?</el-link>
          </div>
        </el-form-item>
        <!-- 登录按钮 -->
        <el-form-item>
          <el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
        </el-form-item>
        <el-form-item class="flex">
          <el-link type="info" :underline="false" @click="isRegister = true;clearRegisterData()">
            注册 →
          </el-link>
        </el-form-item>
      </el-form>
    </el-col>
  </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
  height: 100vh;
  background-color: #fff;

  .bg {
    background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
    url('@/assets/login_bg.jpg') no-repeat center / cover;
    border-radius: 0 20px 20px 0;
  }

  .form {
    display: flex;
    flex-direction: column;
    justify-content: center;
    user-select: none;

    .title {
      margin: 0 auto;
    }

    .button {
      width: 100%;
    }

    .flex {
      width: 100%;
      display: flex;
      justify-content: space-between;
    }
  }
}
</style>

其实以上两者都是对拦截器的响应拦截器进行改进

前端如何传递参数给后端?

前端可以通过多种方式将参数传递给后端。以下是几种常见方法:

1. URL 查询参数(Query Parameters)

使用查询字符串 (GET 请求,通常用于简单查询)

GET 请求中,参数通常附加在 URL 后面,以 ? 开头并用 & 分隔。

javascript 复制代码
	export const articleListService = (params) => {
	   return request.get('/article', { params });
	}

这段代码使用了 axios 库中的 get 方法,其中 { params: params } 将 params 对象中的参数作为查询字符串附加到请求 URL 上。

使用 JSON 格式 (POST 请求,适合较复杂的数据)

如果需要将数据作为 JSON 格式发送,可以使用 POST 请求,并将参数放在请求体中。

javascript 复制代码
export const articleListService = (data) => {
   return request.post('/article', data);
}

表单数据(Form Data)

如果需要上传文件或以表单格式传递数据,可以使用 URLSearchParams

javascript 复制代码
export const userRegisterService = (registerData) => {
    // 需要借助于URLSearchParams完成传递
    const params = new URLSearchParams();
    for (let key in registerData) {
        params.append(key, registerData[key]);
    }

    // 返回请求的Promise,以便前端可以处理响应
    return request.post('/user/register', params);
};

代码说明
URLSearchParams 的使用:通过 URLSearchParams registerData 转换为查询字符串的格式,这是 application/x-www-form-urlencoded 方式传递数据的要求。URLSearchParams 会自动处理编码问题,使特殊字符能够正确传递。

application/x-www-form-urlencoded 方式是什么?

当使用 application/x-www-form-urlencoded 传递数据时,数据会被编码成键值对格式,并将其拼接成查询字符串的形式,类似于 key1=value1&key2=value2。

例子: 假设您有一个包含以下数据的表单:

username = "Alice"

password = "myPass123!"

编码后数据将变成:

bash 复制代码
username=Alice&password=myPass123%21

如果参数格式要求的是JSON格式,可以直接传递

javascript 复制代码
export const userRegisterService = (registerData) => {
    return request.post('/user/register', registerData); // 默认以 JSON 格式发送
};

vue的路由

什么是路由?

Vue 的路由(Router)是一种帮助我们在不同页面之间切换的机制,它让单页面应用(SPA)看起来像多页面应用。

在传统的网页应用中,每次点击链接都会重新加载页面。然而在 Vue 中,路由会"拦截"这些请求,不需要刷新整个页面,而是根据 URL 显示对应的组件,给人一种在多个页面之间切换的感觉。


子路由




API 函数的创建与暴露:

在 api 目录下创建 article.js 文件,提供一个函数用于查询文章分类列表。

这个函数是为了与后端交互,获取所有的文章分类列表数据,并且将该函数导出以供其他组件调用

javascript 复制代码
在ArticleCategory.vue中声明一个异步的函数,来调用接口的articleCategoryListService来获取所有文章的分类列表

前端组件中的 API 调用:

在 ArticleCategory.vue 文件中,导入刚刚在 article.js 中创建的 articleCategoryListService 函数。

使用一个异步函数来调用该服务 (articleCategoryListService),并获取所有的文章分类列表数据。

将返回的数据赋值给一个变量(如 categorys),以便在页面上渲染分类信息。

javascript 复制代码
// 声明一个异步的函数,来调用接口的articleCategoryListService来获取所有文章的分类列表
import {articleCategoryListService}from '@/api/article.js'
const articleCategoryList = async ()=>{
  let result = await articleCategoryListService();
  categorys.value = result.data;// 返回的数据的data数组赋值给categorys
}
articleCategoryList();

以上描述的步骤是实现文章分类列表查询功能的过程,具体分为以下几个步骤:

错误及原因说明:

在调用文章分类列表查询时,出现了 401 错误。

401 错误通常表示未授权访问,原因可能是请求中没有携带身份验证

Pinia

图片中可以看到,Pinia 是 Vue 的一个专属状态管理库,它类似于 Vuex,用于管理跨组件或跨页面的共享状态。在这个示例中,Pinia作为状态管理库存储了一个 token,并且 Login.vue 和 ArticleCategory.vue 这两个组件都可以从 Pinia 中获取这个 token,实现数据共享。

stores/token.js:

javascript 复制代码
// 定义store

import {defineStore} from 'pinia'
import {ref} from 'vue'

/*
第一个参数:名字,具有唯一性
第二个参数:函数,函数内部可以定义状态的所有内容

返回值:函数
 */
export const useTokenStore = defineStore('token',()=>{
    // 定义状态的内容

    // 1. 响应式变量
    const token = ref('')
    // 2. 定义一个函数,修改token的值
    const setToken = (newToken) =>{
        token.value = newToken
    }
    // 3. 函数,移除token
    const removeToken = () =>{
        token.value=''
    }
    return{
        token,setToken,removeToken
    }
});

article.js

javascript 复制代码
import request from "@/utils/request.js";
import {useTokenStore} from "@/stores/token.js";
// 文章分类列表查询
export const articleCategoryListService = ()=>{
    // 先得到状态
    const tokenStore = useTokenStore();
    // 在pinia中定义的响应数据都不是需要value,直接使用
    return request.get('/category',{headers:{'Authorization':tokenStore.token}});
}

Pinia 的作用和一般用途:

状态管理:Pinia 提供了一个中心化的存储来管理应用的状态,可以在不同组件之间共享数据,避免了频繁的父子组件传递数据的问题。

解决状态同步问题:Pinia 可以同步和持久化状态,适合需要在多个组件中共享或操作同一个状态的场景。例如,登录后的 token 信息可以存储在 Pinia 中,其他需要用到 token 的组件可以直接从 Pinia 获取,而不需要逐层传递或依赖单一组件。

简化跨组件通信:在大型应用中,组件间的数据共享和通信可能会变得复杂。Pinia 提供了一个统一的状态管理,使数据管理更清晰、结构更合理。

例如,在用户登录后,可以将用户的 token 和其他个人信息(如用户名、邮箱、头像等)存储在 Pinia 中,这样可以让整个应用的不同组件轻松访问这些信息,而无需在组件间传递。

进一步优化

如果每一次请求都需要携带token,实在是太麻烦了,所以我们可以进行优化,在请求的时候添加请求拦截器,也就是把重复的代码放在Axios的请求拦截器中(同意wield请求头携带token)

javascript 复制代码
import { useTokenStore } from "@/stores/token.js";
//添加请求拦截器
instance.interceptors.request.use(
    result => {
        // 请求前的回调
        // 添加token
        const tokenStore = useTokenStore();
        if (tokenStore.token) {
            result.headers.Authorization = tokenStore.token;
        }
        return result;
    },
    error => {
        // 请求错误的回调
        return Promise.reject(error);
    }
);

persist

之前使用Pinia存在一个bug

那就是刷新过后获取不到对应的文章分类了

该如何解决?

Pinia 的 persist 插件用于持久化存储数据。通过它,存储在 Pinia 状态管理中的数据可以保存在浏览器的 localStorage 或 sessionStorage 中,从而在页面刷新或重新加载后依然可以保持数据不丢失。这对于用户登录状态、用户偏好设置等数据的持久化非常有用。

注意!!这里实在Pinia中使用persist,不是在app中使用了

main.js

javascript 复制代码
import { createPinia } from 'pinia';
import './assets/main.scss'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { createApp } from 'vue'
import App from './App.vue'

// 默认找到index文件
import router from '@/router'
import {createPersistedState} from "pinia-persistedstate-plugin";

const app = createApp(App);
const pinia = createPinia(); // 创建 Pinia 实例
const persist = createPersistedState();
pinia.use(persist)
app.use(ElementPlus)
app.use(router)
app.use(pinia)
app.mount('#app')

token.js

javascript 复制代码
// 定义store
import {defineStore} from 'pinia'
import {ref} from 'vue'

/*
第一个参数:名字,具有唯一性
第二个参数:函数,函数内部可以定义状态的所有内容

返回值:函数
 */
export const useTokenStore = defineStore('token',()=>{
        // 定义状态的内容

        // 1. 响应式变量
        const token = ref('')
        // 2. 定义一个函数,修改token的值
        const setToken = (newToken) =>{
            token.value = newToken
        }
        // 3. 函数,移除token
        const removeToken = () =>{
            token.value=''
        }
        return{
            token,setToken,removeToken
        }
    },{
        persist:true // 持久化存储
    }
);

对未登录的状态需要进行统一的处理:

在之前的代码中,如果用户没有登录,直接访问的文章列表的分类那么就只会报出服务异常,没有别的操作来处理未登录的状态,比如说是跳转到登录页面 ,这个时候我们就可以使用 路由器,用于在未登录状态下将用户重定向到登录页面。所以我们可以继续完善我们的响应拦截器。

在拦截器中,当检测到 err.response.status === 401(未登录状态)时,使用router.push('/login') 将用户导航到登录页面 (/login 路由)。这是 Vue Router 的典型用法,用于在客户端应用中控制页面跳转。

数据回显

数据回显是指在页面或表单中,将已有的数据展示给用户的一种操作。通常用于编辑页面、查看详情页面或者提交后的反馈页面,使用户可以看到之前输入或已有的信息。这种操作帮助用户确认、修改或重新查看数据内容。

例如:

当点击修改分类按钮时,需要把当前这一条数据的详细信息显示到修改分类的弹窗上,这个叫回显。

详细步骤如下:

  1. 监听修改按钮的点击事件

    每一行数据旁边有一个"修改分类"按钮,当用户点击这个按钮时,会触发一个事件。这个事件的作用就是 获取到当前这条数据的详细信息,并将数据传递给弹窗组件。

  2. 获取数据并传递给弹窗

    获取当前行的数据,可以有两种方式:

从列表数据中直接获取:如果当前行的数据已经存在于页面的列表数据中,可以直接将这条数据传递给弹窗。

从后端请求:如果数据可能已经被其他用户修改或页面中的数据不全,可以通过点击事件发送请求到后台,获取最新的详细数据。

相关推荐
文心快码BaiduComate2 小时前
再获殊荣!文心快码荣膺2025年度优秀软件产品!
前端·后端·代码规范
Mintopia2 小时前
🚀 Next.js 后端能力扩展:错误处理与 HTTP 状态码规范
前端·javascript·next.js
IT酷盖2 小时前
Android解决隐藏依赖冲突
android·前端·vue.js
mwq301232 小时前
RNN 梯度计算详细推导 (BPTT)
前端
mogexiuluo2 小时前
kali下安装beef-xss报错-启动失败-简单详细
前端·xss
y_y2 小时前
Streamable HTTP:下一代实时通信协议,解决SSE的四大痛点
前端·http
无羡仙2 小时前
流式输出SSE
前端
小噔小咚什么东东3 小时前
Vue开发H5项目中基于栈的弹窗管理
前端·vue.js·vant
OpenTiny社区3 小时前
基于华为云大模型服务MaaS和OpenTiny框架实现商城商品智能化管理
前端·agent·mcp