溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

不使用Vuex如何封裝登錄狀態判斷

發布時間:2022-02-18 09:03:38 來源:億速云 閱讀:161 作者:iii 欄目:編程語言
# 不使用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
  }
}

1.2 在組件中使用

<script setup>
import { useAuth } from '@/composables/useAuth'

const { isAuthenticated, login, logout } = useAuth()
</script>

二、狀態持久化方案

2.1 結合localStorage

// 增強版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()
}

2.2 處理Token過期(JWT示例)

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()

三、跨組件狀態共享

3.1 Provide/Inject模式

// 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>

3.2 全局狀態模式

// src/utils/auth.ts
export const authState = {
  isAuthenticated: false,
  // ...其他狀態
}

// 組件中直接導入使用
import { authState } from '@/utils/auth'

四、路由守衛集成

4.1 基礎路由守衛實現

// 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'
  }
})

4.2 動態權限控制

// 路由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'
  }
})

五、完整實現示例

5.1 增強版useAuth.ts

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字,可根據需要調整各部分詳略程度。代碼示例需要根據實際項目技術棧進行調整。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女