什么是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 中的传统风格,它通过配置对象的方式将逻辑分散到不同的选项(如 data
、methods
、computed
等)中。适合组件逻辑简单、容易分离的场景。
- 常用选项:
data
:定义组件的响应式数据。methods
:定义组件的方法。computed
:定义计算属性。watch
:监视响应式数据的变化。props
、emits
:用于定义组件的输入和输出。- 示例:
javascript
export default {
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
}
};

2. 组合式 API (Composition API)
组合式 API 是在 Vue 3 中引入的新风格,通过函数(如 setup
)将逻辑聚合到一起,提升代码复用性和灵活性。适合复杂逻辑的场景,尤其是在组件需要多个逻辑模块时。
- 特点:
- 提供更高的灵活性和可复用性。
- 更适合复杂逻辑,逻辑更集中、模块化。
- 支持直接导入 Vue 的核心 API,如
ref
、computed
、watch
。 - 核心 API:
ref
:定义响应式变量。reactive
:定义响应式对象。computed
:创建计算属性。watch
和watchEffect
:监听响应式数据的变化。provide
和inject
:在组件间提供和注入数据。示例:
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接口的优化

- 发现问题 :在项目中,每次 API 请求都需要写
.then
和.catch
来处理响应和错误,导致代码重复,维护困难。 - 解决方案 :将 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;
- 使用封装的 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 });
}
- 调用 API :在组件或其他业务逻辑中调用
articleGetAllService
或articleSearchService
,简化代码逻辑。
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 的典型用法,用于在客户端应用中控制页面跳转。
数据回显
数据回显是指在页面或表单中,将已有的数据展示给用户的一种操作。通常用于编辑页面、查看详情页面或者提交后的反馈页面,使用户可以看到之前输入或已有的信息。这种操作帮助用户确认、修改或重新查看数据内容。
例如:
当点击修改分类按钮时,需要把当前这一条数据的详细信息显示到修改分类的弹窗上,这个叫回显。
详细步骤如下:
-
监听修改按钮的点击事件
每一行数据旁边有一个"修改分类"按钮,当用户点击这个按钮时,会触发一个事件。这个事件的作用就是 获取到当前这条数据的详细信息,并将数据传递给弹窗组件。
-
获取数据并传递给弹窗
获取当前行的数据,可以有两种方式:
从列表数据中直接获取:如果当前行的数据已经存在于页面的列表数据中,可以直接将这条数据传递给弹窗。
从后端请求:如果数据可能已经被其他用户修改或页面中的数据不全,可以通过点击事件发送请求到后台,获取最新的详细数据。