您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 不使用Vuex如何封装登录状态判断
## 前言
在Vue.js项目中,状态管理通常首选Vuex。但对于小型项目或简单场景,引入Vuex可能显得过于繁重。本文将探讨如何在不使用Vuex的情况下,通过自定义封装实现登录状态判断,包括以下核心方案:
1. 使用Composition API的响应式状态
2. 利用浏览器本地存储持久化状态
3. 通过Provide/Inject实现跨组件状态共享
4. 路由守卫的集成方案
---
## 一、Composition API响应式状态管理
### 1.1 创建auth状态模块
```typescript
// src/composables/useAuth.ts
import { ref, computed } from 'vue'
const isAuthenticated = ref(false)
const user = ref<null | { name: string; email: string }>(null)
export function useAuth() {
// 登录方法
const login = (userData: { name: string; email: string }) => {
isAuthenticated.value = true
user.value = userData
}
// 登出方法
const logout = () => {
isAuthenticated.value = false
user.value = null
}
// 计算属性
const isAdmin = computed(() => user.value?.email.endsWith('@admin.com'))
return {
isAuthenticated: computed(() => isAuthenticated.value),
user: computed(() => user.value),
isAdmin,
login,
logout
}
}
<script setup>
import { useAuth } from '@/composables/useAuth'
const { isAuthenticated, login, logout } = useAuth()
</script>
// 增强版useAuth.ts
function loadFromStorage() {
const saved = localStorage.getItem('auth')
if (saved) {
const parsed = JSON.parse(saved)
isAuthenticated.value = parsed.isAuthenticated
user.value = parsed.user
}
}
function saveToStorage() {
localStorage.setItem('auth', JSON.stringify({
isAuthenticated: isAuthenticated.value,
user: user.value
}))
}
// 修改后的login方法
const login = (userData) => {
isAuthenticated.value = true
user.value = userData
saveToStorage()
}
function checkTokenExpiry() {
const token = localStorage.getItem('token')
if (token) {
const { exp } = JSON.parse(atob(token.split('.')[1]))
if (Date.now() >= exp * 1000) {
logout()
}
}
}
// 初始化时调用
loadFromStorage()
checkTokenExpiry()
// main.ts或顶层组件
import { provide } from 'vue'
import { useAuth } from './composables/useAuth'
const auth = useAuth()
provide('auth', auth)
<!-- 子组件 -->
<script setup>
import { inject } from 'vue'
const auth = inject('auth')
</script>
// src/utils/auth.ts
export const authState = {
isAuthenticated: false,
// ...其他状态
}
// 组件中直接导入使用
import { authState } from '@/utils/auth'
// src/router.ts
import { createRouter } from 'vue-router'
import { useAuth } from './composables/useAuth'
const router = createRouter({ /* routes配置 */ })
router.beforeEach((to) => {
const { isAuthenticated } = useAuth()
if (to.meta.requiresAuth && !isAuthenticated.value) {
return '/login'
}
if (to.meta.guestOnly && isAuthenticated.value) {
return '/dashboard'
}
})
// 路由meta配置示例
{
path: '/admin',
meta: {
requiresAuth: true,
requiredRole: 'admin'
}
}
// 增强版守卫
router.beforeEach((to) => {
const { isAuthenticated, isAdmin } = useAuth()
if (to.meta.requiresAuth && !isAuthenticated.value) {
return '/login'
}
if (to.meta.requiredRole === 'admin' && !isAdmin.value) {
return '/403'
}
})
import { ref, computed, watchEffect } from 'vue'
// 状态定义
const state = ref({
isAuthenticated: false,
user: null,
token: null
})
// 持久化处理
function syncWithStorage() {
const saved = localStorage.getItem('auth')
if (saved) {
state.value = JSON.parse(saved)
}
watchEffect(() => {
localStorage.setItem('auth', JSON.stringify(state.value))
})
}
// Token处理
function validateToken() {
if (state.value.token) {
const { exp } = JSON.parse(atob(state.value.token.split('.')[1]))
return Date.now() < exp * 1000
}
return false
}
export function useAuth() {
syncWithStorage()
return {
state: computed(() => state.value),
login(userData) {
state.value = {
isAuthenticated: true,
user: userData,
token: generateToken(userData) // 假设的token生成
}
},
logout() {
state.value = {
isAuthenticated: false,
user: null,
token: null
}
},
checkAuth() {
return state.value.isAuthenticated && validateToken()
}
}
}
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Composition API | 小型应用/简单状态 | 轻量、组合性强 | 跨组件共享稍复杂 |
| Provide/Inject | 中等规模组件树 | 显式依赖关系 | 不宜深层嵌套 |
| localStorage | 需要持久化的状态 | 页面刷新不丢失 | 需处理安全性和同步 |
| 全局状态对象 | 简单全局状态 | 实现最简单 | 难以追踪状态变化 |
技术选型建议: - 小型项目:Composition API + localStorage - 需要SSR的项目:避免使用浏览器API,考虑Cookie方案 - 中型项目:仍建议使用Pinia等轻量状态库
通过合理的封装,我们完全可以在不使用Vuex的情况下实现完善的登录状态管理。关键点在于: 1. 选择适合项目规模的共享方案 2. 处理好状态持久化 3. 与路由系统深度集成 4. 保持代码的可维护性和可测试性
随着Vue 3生态的发展,Composition API已经能够满足大多数状态管理需求,开发者可以根据项目实际情况灵活选择方案。 “`
注:实际字数约1500字,可根据需要调整各部分详略程度。代码示例需要根据实际项目技术栈进行调整。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。