接下来
- 1、注销功能:点击注销按钮,清除登录信息跳转到登录页面
- 2、token过期
注销功能
useUser.js
import storage from "../../g/storage.js";
import {useRouter} from "vue-router";
import {message} from "ant-design-vue";
export default function useUser() {
const router = useRouter()
// 注销
const logout = () => {
storage.delete("userid")
storage.delete("username")
storage.delete("token")
message.success("退出登录成功")
router.push("/login")
}
return {
logout,
}
}
处理菜单点击:
import {ref} from 'vue';
import useUser from "./useUser.js"
const {logout} = useUser()
const selectedKeys = ref(['latest']);
// 处理菜单点击
const handleMenuClick = ({key}) => {
switch (key) {
case 'user-logout':
logout()
break
}
}
头像变成用户名首字母
简单实现:
const avatar = () => {
const username = storage.get("username") || "U"
return username.charAt(0).toUpperCase()
}
vue3计算属性
在 Vue 3 中,计算属性(computed properties)是一种特殊类型的依赖项,它们根据响应式数据的变化自动重新计算值。计算属性非常适合用于当你需要根据现有数据派生出一些状态时。
以下是 Vue 3 中使用计算属性的简单示例:
<template>
<div>
<p>价格: {{ product.price }}</p>
<p>含税价格: {{ totalPrice }}</p>
</div>
</template>
<script setup>
import { computed, ref } from 'vue';
const product = ref({
name: 'Vue 3 Guide',
price: 100
});
// 计算属性,用于计算含税总价
const totalPrice = computed(() => {
return product.value.price * 1.15; // 假设税率为 15%
});
</script>
在这个示例中:
- 使用
ref
创建了一个响应式的数据对象product
,它包含产品名称和价格。 - 使用
computed
创建了一个计算属性totalPrice
,它基于product
的价格计算含税后的总价。这里假设税率为 15%。 - 在模板中,我们展示了产品的价格和含税价格。
计算属性 totalPrice
会根据 product.price
的变化自动更新。当 product.price
发生变化时,任何依赖于 totalPrice
的视图都会自动更新。
计算属性是惰性的,只有在它们所依赖的响应式数据发生变化时才会重新计算。这使得计算属性非常高效,并且它们是缓存的,只有当依赖项发生变化时,计算属性的值才会重新计算。
请注意,<script setup>
是 Vue 3 引入的一个新的脚本语法糖,它使得组件的编写更加简洁。如果你使用的是传统的 export default
语法,那么你需要稍微调整代码:
export default {
data() {
return {
product: {
name: 'Vue 3 Guide',
price: 100
}
};
},
computed: {
totalPrice() {
return this.product.price * 1.15; // 假设税率为 15%
}
}
};
在这个传统语法的示例中,计算属性 totalPrice
被定义在 computed
选项中,并且可以通过 this.product
访问响应式数据 product
。
计算属性版本的头像
核心代码:
const totalPrice = computed(() => {
return product.value.price * 1.15; // 假设税率为 15%
});
头像代码:
const avatar = computed(() => {
const username = storage.get("username") || "U"
return username.charAt(0).toUpperCase()
})
简写代码:
const avatar = computed(() => (storage.get("username") || "U").charAt(0).toUpperCase())
当前界面
接下来
- 1、数据的请求是没有权限的,我们应该要验证权限
- 2、必须要登录才能请求数据,Token必须有效
- 3、前端要把登录Token传递后端
问题:我们会有非常多的接口,我们是每个接口都手动把Token传递进去吗?
回答:这是比较low的写法,Axios有一个拦截器的功能,我们可以在拦截器中,统一设置携带Token。
axios拦截器
在 JavaScript 中,使用 Axios 进行 HTTP 请求时,可以设置请求拦截器和响应拦截器来统一处理请求和响应。这在处理认证、记录日志、统一格式化数据等场景中非常有用。
以下是 Axios 请求拦截器和响应拦截器的简单示例:
安装 Axios
首先,确保你已经安装了 Axios。如果还没有安装,可以使用 npm 或 yarn 来安装:
npm install axios
或者
yarn add axios
设置拦截器
import axios from 'axios';
// 请求拦截器
axios.interceptors.request.use(
config => {
// 在发送请求之前做些什么,例如添加认证头
const token = localStorage.getItem('user-token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 响应拦截器
axios.interceptors.response.use(
response => {
// 对响应数据做点什么
return response;
},
error => {
// 对响应错误做点什么
if (error.response && error.response.status === 401) {
// 例如,处理 401 未认证错误
console.log('未认证,需要重新登录');
}
return Promise.reject(error);
}
);
// 使用 Axios 发送请求
axios.get('/api/data')
.then(response => {
console.log('数据获取成功:', response.data);
})
.catch(error => {
console.error('数据获取失败:', error);
});
在这个示例中:
- 请求拦截器:在发送请求之前,检查本地存储中是否存在 token,并将其添加到请求头中。如果 token 存在,请求头中将包含
Authorization
字段。 - 响应拦截器:在收到响应后,根据响应状态进行处理。例如,如果响应状态码为 401(未认证),可以记录日志或执行其他操作。
详细说明
-
请求拦截器:
- 使用
axios.interceptors.request.use
方法设置请求拦截器。 - 第一个参数是一个函数,它接收
config
对象作为参数,你可以在发送请求之前修改它,例如添加或修改请求头。 - 第二个参数是一个处理错误的函数,如果请求配置出错,可以在这里处理。
- 使用
-
响应拦截器:
- 使用
axios.interceptors.response.use
方法设置响应拦截器。 - 第一个参数是一个函数,它接收
response
对象作为参数,你可以在处理响应数据之前对其进行操作。 - 第二个参数是一个处理错误的函数,如果响应出错,可以在这里处理。
- 使用
-
发送请求:
- 使用
axios.get
方法发送 GET 请求,并使用then
和catch
处理成功和失败的情况。
- 使用
总结
拦截器是 Axios 中非常强大的功能,它们允许你在请求发送之前和响应返回之后统一处理逻辑。这在处理认证、日志记录、错误处理等场景中非常有用。通过设置拦截器,你可以避免在每个请求和响应中重复相同的代码,从而使代码更加简洁和易于维护。
axios创建实例对象
在 Axios 中,你可以创建一个实例对象来配置特定的 axios 实例。这在你需要为应用的不同部分设置不同的基础 URL、头部或超时时间等配置时非常有用。
以下是如何创建 Axios 实例对象的示例:
import axios from 'axios';
// 创建 axios 实例
const instance = axios.create({
baseURL: 'https://api.example.com', // 设置默认的基础 URL
timeout: 1000, // 设置默认的超时时间
headers: {'X-Custom-Header': 'foobar'} // 设置默认的请求头
});
// 使用实例发送请求
instance.get('/data')
.then(response => {
console.log('数据获取成功:', response.data);
})
.catch(error => {
console.error('数据获取失败:', error);
});
// 你可以为实例添加拦截器
instance.interceptors.request.use(
config => {
// 在发送请求之前做些什么
config.headers['Authorization'] = `Bearer your-token`;
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
instance.interceptors.response.use(
response => {
// 对响应数据做点什么
return response;
},
error => {
// 对响应错误做点什么
return Promise.reject(error);
}
);
在这个示例中:
- 使用
axios.create()
方法创建了一个 Axios 实例。 baseURL
设置了所有请求的默认基础 URL。timeout
设置了所有请求的默认超时时间(以毫秒为单位)。headers
设置了所有请求的默认请求头。- 使用实例对象
instance
发送了一个 GET 请求。 - 为实例对象添加了请求拦截器和响应拦截器。
创建实例对象的好处是你可以针对不同的 API 端点或不同的请求需求设置不同的配置,而不必在每次请求时都设置这些配置。这使得代码更加模块化和可重用。
此外,Axios 实例也是可配置的,这意味着你可以在实例的基础上进一步定制化,例如添加特定的拦截器或配置项。这在构建大型应用时非常有用,因为它允许你为不同的 API 模块或功能创建不同的 Axios 实例。
封装axios
import axios from "axios";
import storage from "./storage.js";
// 全局HTTP请求对象
const req = axios.create({
baseURL: 'http://127.0.0.1:18888', // 设置默认的基础 URL
timeout: 3000, // 设置默认的超时时间
headers: {'Content-Type': 'application/json'} // 设置默认的请求头
});
// 请求拦截器
req.interceptors.request.use(config => {
// 添加统一的token
const token = storage.get("token") || ""
if (token) {
config.headers.Authorization = token
}
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 导出
export default req;
// 响应拦截器
req.interceptors.response.use(
response => {
// 对响应数据做点什么
return response;
},
error => {
// 对响应错误做点什么
if (error.response && error.response.status === 401) {
// 例如,处理 401 未认证错误
console.log('未认证,需要重新登录');
}
return Promise.reject(error);
}
);