Vue3+Vite+TypeScript+Element Plus开发-16.登录退出
系列文档目录
Vue3+Vite+TypeScript安装
Element Plus安装与配置
主页设计与router配置
静态菜单设计
Pinia引入
Header响应式菜单缩展
Mockjs引用与Axios封装
登录设计
登录成功跳转主页
多用户动态加载菜单
Pinia持久化
动态路由 -动态增加路由
动态路由-动态删除路由
路由守卫-无路由跳转404
路由守卫-未登录跳转登录界面
登录退出
Tags-组件构建
Tags-与菜单联动
Pinia持久化优化
按钮权限
客制按钮组件
客制Table组件
客制Form组件
国际化
配置文件
文章目录
目录
系列文档目录
文章目录
前言
一、修改存储
二、修改header组件
三、运行测试
编辑四、持续优化
五、完美呈现
后续
前言
上一章节讨论了未登录时自动跳转至登录界面的功能。为配合该功能,本章节将重点构建登录与退出机制。
一、修改存储
增加logout对存储清除。
// 登出方法logout() {sessionStorage.removeItem('useAllData-store'); // 清除 sessionStorage 中的数据this.username = '';this.token_key = '';this.menuData = [];router.push({ name: 'login' }); // 重定向到登录页面},
优化后完整代码:
// src/stores/index.tsimport { defineStore } from 'pinia';
import router from '../router';
import type { Component } from 'vue';type Modules = Record<string, () => Promise<{ default: Component }>>;// 定义公共 store
export const useAllDataStore = defineStore('useAllData', {// 定义状态state: () => ({isCollapse: false, // 定义初始状态username: '',token_key: '',menuData:[],}),// 定义 actionsactions: {// 设置用户名setUsername(username: string) {this.username = username;},// 获取用户名getUsername(): string {return this.username;},// 设置 token_keysetTokenKey(token_key: string) {// sessionStorage.setItem('useAllData-session-store', JSON.stringify({ token_key: token_key, menuData: this.menuData}));this.token_key = token_key;},// 获取 token_keygetTokenKey(): string {/*const sessionData = sessionStorage.getItem('useAllData-session-store');console.log(sessionData)if (sessionData) {const data = JSON.parse(sessionData);this.token_key = data.token_key;this.menuData = data.menuData;}else{this.token_key = ''}*/return this.token_key;},// 设置菜单数据setMenuData(menuData: any){// sessionStorage.setItem('useAllData-session-store', JSON.stringify({ token_key: this.token_key, menuData: menuData}));addRouter(menuData)this.menuData = menuData},// 获取菜单数据getMenuData(): [] {return this.menuData;},// 登出方法logout() {sessionStorage.removeItem('useAllData-store'); // 清除 sessionStorage 中的数据this.username = '';this.token_key = '';this.menuData = [];router.push({ name: 'login' }); // 重定向到登录页面},},persist: {enabled: true,key: 'useAllData-store',storage: sessionStorage, // // localStorage sessionStoragepaths: ['token_key'], // 指定持久化的字段},/*persist: {enabled: true,strategies: [{key: 'useAllData-store',storage: sessionStorage,// localStorage sessionStoragepaths: ['token_key','menuData'], // 指定需要持久化的字段},],},*/});function addRouter(menuData: any){const routerList=router.getRoutes()const modules: Modules = import.meta.glob('../views/**/*.vue') as Modules;const routerArr=[]menuData.forEach((item:any) => {// console.log(item) if(item.children){item.children.forEach((child:any) => {const componentPath = `../${child.path}.vue`;const module = modules[componentPath];if (module) {/*module().then(({ default: component }) => {child.component = component;});*/child.component = module;routerArr.push(child)}});}else{const componentPath = `../${item.path}.vue`;const module = modules[componentPath];if(module){item.component = module;routerArr.push(item)}}});// 增加删除路由routerList.forEach((item:any) => {if (item.name === 'main' || item.name === 'home' || item.name === '404' || item.name === 'login'|| item.name === 'error'|| item.name === 'undefined'|| item.path === '/'|| item.path === '/main') returnrouter.removeRoute(item.name)});routerArr.forEach((item:any) => {router.addRoute('main',{path: item.index,name: item.label,component: item.component,});})
const routerListLast=router.getRoutes()
console.log(routerListLast)}export function ReloadData() {const store = useAllDataStore();const menuData = store.getMenuData();addRouter(menuData);}
二、修改header组件
在 components/MainHdrCont.vue 中,增加了退出登录的处理逻辑。
<template><!-- 顶部导航栏 --><div class="header-layout"><div class="header-left"><div class="mb-4"> <el-button type="primary" :key="bntMenuText" @click="handleMenu">{{bntMenuText}}</el-button></div></div><div class="header-right"><el-dropdown><span class="el-dropdown-link"><el-avatar :size="30" src="../assets/vue.svg" /><el-icon><ArrowDown /></el-icon></span><template #dropdown><el-dropdown-menu><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>设置</el-dropdown-item><el-dropdown-item @click="handleLogout">退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></div></template><script lang="ts" setup>import { ref,computed,defineComponent } from 'vue';import { useAllDataStore } from '@/stores';const store = useAllDataStore();// 定义按钮文本,根据 store.isCollapse 的值动态设置const bntMenuText = computed(() => {return store.isCollapse ? 'expand' : 'collapse';});// 定义单击事件的处理函数function handleMenu() {store.isCollapse =! store.isCollapse// 在这里可以添加更多逻辑,例如切换菜单状态}function handleLogout() {store.logout();
}/*export const MainAHdrCont = defineComponent({name: 'MainAHdrCont'});*/</script><style scoped>.header-layout {display: flex; justify-content: space-between; /* 使 header-left 和 header-right 分别靠左和靠右 */align-items: center;width: 100%; /* 确保 header 占据整个容器宽度 */}.header-left {display: flex;align-items: center;}.header-right {display: flex;align-items: center;}</style>
三、运行测试

四、持续优化
优化logout 功能,重点隐藏清除操作后的赋值过程,目的是避免在存储中显示该存储键(Key)
// 登出方法logout() {sessionStorage.removeItem('useAllData-store'); // 清除 sessionStorage 中的数据/*this.username = '';this.token_key = '';this.menuData = [];*/router.push({ name: 'login' }); // 重定向到登录页面
},
当前修改虽有进展,但在后续开发中发现了一些问题。为了保证程序的正确运行,此处暂不使用优化后的代码,还请见谅。本系列文章仅为初学者的开发笔记,后续章节将对该问题进行进一步优化,并专门讲解 Pinia 持久化的优化及清除机制。以下是部分优化代码的剧透:
持久化存储改变:
persist: [{enabled: true,key: 'useAllData-store',storage: sessionStorage, // // localStorage sessionStoragepick: ['token_key','tabs','menuData','permissions','currentPagePath'], // 指定持久化的字段},{key: 'useAllData-store',storage: localStorage, // // localStorage sessionStoragepick: ['username','isCollapse'], // 指定持久化的字段},],
main.ts 对Pinia持久化定义改变:
//import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import { createPersistedState } from 'pinia-plugin-persistedstate'/ 使用插件// pinia.use(piniaPluginPersistedstate);pinia.use(createPersistedState({key: id => `__persisted__${id}`,storage: sessionStorage,}))
logout重新定义:
resetStore(){//console.log('sessionStorage clear:', sessionStorage.length === 0); // 应该输出 true this.$reset(); // 重置 Pinia 状态//console.log('sessionStorage reset:', sessionStorage.length === 0); // 应该输出 true //sessionStorage.clear(); // 清空 sessionStoragesessionStorage.removeItem('__persisted__useAllData-store');//console.log('sessionStorage cleared:', sessionStorage.length === 0); // 应该输出 true // Object.assign(this, stateIni()); // 复制 Pinia 状态// sessionStorage.removeItem('useAllData-store'); // 删除 sessionStorage 中的数据},// 登出方法logout() {this.resetStore() // console.log('sessionStorage reset:', sessionStorage.length === 0); // 应该输出 true // sessionStorage.removeItem('useAllData-store'); // 删除 sessionStorage 中的数据// console.log('sessionStorage clear:', sessionStorage.length === 0); // 应该输出 true // router.push({ name: 'login' }); // 重定向到登录页面// 检查登录后的逻辑router.push({ name: 'login' }).then(() => {// console.log('Navigated to login page');// console.log('sessionStorage after navigation:', sessionStorage.length === 0); // 确认是否仍然为 true});},
五、完美呈现

后续
本章节将重点构建登录与退出机制。下一章节主要讨论Tags功能,即在打开菜单时,每个页面都会在Tags中显示。
代码下载
GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。
https://gitcode.com/sen_shan/ssVue3Demo.git ss.vue3.demo: 本项目以 Vue3、Vite、TypeScript、Element Plus 为核心框架,结合 Vue Router、Element Plus Icons、Less、Axios、Pinia、Mock 等技术,初始的构建登录,主界面,权限控制,按钮组件,table组件,form组件等小模型,可以随意搭建web管理系统
https://gitee.com/sen_shan/ssVue3Demo.git
