第八节:Element Plus 基础、封装通用组件 + 路由守卫

第八节:Element Plus 基础、封装通用组件 + 路由守卫

本节目标:

  1. 写全局路由守卫,未登录拦截跳登录页
  2. Pinia 数据持久化(刷新页面 token 不丢失)
  3. 封装一个简单全局通用组件示例
  4. 完善退出登录功能

步骤 1:Pinia 持久化(本地存储 localStorage)

修改 src/stores/user.js

复制代码
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    token: localStorage.getItem('token') || '',
    username: localStorage.getItem('username') || ''
  }),
  getters: {
    isLogin: (state) => !!state.token
  },
  actions: {
    setUserInfo(token, username) {
      this.token = token
      this.username = username
      // 存入本地存储
      localStorage.setItem('token', token)
      localStorage.setItem('username', username)
    },
    logout() {
      this.token = ''
      this.username = ''
      localStorage.removeItem('token')
      localStorage.removeItem('username')
    }
  }
})

步骤 2:配置全局路由守卫 src/router/index.js

在文件末尾追加守卫代码

复制代码
// 路由守卫
router.beforeEach((to, from, next) => {
  const userStore = useUserStore()
  // 访问登录页直接放行
  if (to.path === '/login') {
    next()
  } else {
    // 判断是否有token
    if (userStore.isLogin) {
      next()
    } else {
      // 没有token跳登录
      next('/login')
    }
  }
})

export default router

⚠️注意:需要在 router 顶部导入 userStore

复制代码
import { useUserStore } from '@/stores/user'

完整的 src/router/index.js 头部片段:

复制代码
import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores/user'
// 布局组件
const Layout = () => import('@/layout/index.vue')

步骤 3:封装一个全局通用组件示例

新建 src/components/PageCard.vue,后台页面通用卡片容器,components 与 layout 同级

复制代码
<template>
  <el-card class="page-card">
    <template #header>
      <div class="card-header">
        <span>{{ title }}</span>
      </div>
    </template>
    <slot></slot>
  </el-card>
</template>

<script setup>
defineProps({
  title: {
    type: String,
    default: ''
  }
})
</script>

<style scoped>
.page-card {
  margin: 10px;
}
.card-header {
  font-weight: bold;
  font-size: 16px;
}
</style>

修改后台首页 src/views/dashboard/index.vue,测试我们封装的 PageCard 组件

复制代码
<template>
  <div>
    <PageCard title="系统首页看板">
      <p>欢迎进入仿若依Vue3 Setup后台管理系统</p>
      <el-button type="danger" @click="handleLogout">退出登录</el-button>
    </PageCard>
  </div>
</template>

<script setup>
import { useUserStore } from '@/stores/user'
import { useRouter } from 'vue-router'

const userStore = useUserStore()
const router = useRouter()

const handleLogout = () => {
  userStore.logout()
  ElMessage.success('已退出登录')
  router.push('/login')
}
</script>

因为配置了 unplugin 自动导入,PageCard组件不需要手动 import,直接使用。

✅第八节测试

  1. 重启 pnpm dev
  2. 直接在浏览器地址栏访问 /dashboard/index
    • 没有登录,自动拦截跳转 /login ✔
  3. 使用账号admin / 123456登录成功,进入首页
  4. 刷新浏览器页面:token、用户信息不会丢失(localStorage 持久化生效)✔
  5. 首页看到封装的 PageCard 卡片,点击【退出登录】,清空信息,跳回登录页 ✔
  6. F12 控制台无报错。

注意:此时 Layout 布局还只是简单占位,下一节正式开发完整 Layout(侧边栏、头部、折叠按钮)。

相关推荐
牛奔16 分钟前
mise 管理多版本 Go 项目
开发语言·前端·chrome·后端·golang
志尊宝44 分钟前
Vue3 零基础每日笔记(076):防抖节流的正确使用——搜索框、按钮防重复提交、滚动监听
javascript·vue.js·笔记
顽疲1 小时前
从零用 Java 实现小红书 SpringBoot Vue UniApp(23)笔记话题多对多:一条笔记进多个话题池
java·vue.js·spring boot
能源革命1 小时前
Vue 网格拖拽布局组件全景指南:7 大方案深度对比
前端·javascript·vue.js
PC2005_cloud2 小时前
AI 汉字漂移实录:它为什么总把「学习」写成日语「学習」
前端·后端
穆梓兰煊2 小时前
AI供应链安全不再只是包安全,还涉及模型与数据
前端·数据库
RaaS1002 小时前
AI网关能做Prompt注入防护吗?AI网关核心功能详解
前端·后端
deli0072 小时前
Skill 怎么写才被 Agent 命中?18 条规则做成 SKILL.md 校验器,规范样例 92 分
前端
Hum8le2 小时前
CTF题目《easy_web》(安洵杯 2019 变种 Web)
前端·安全·web安全
coding漫漫长路2 小时前
二值化后还剩1212个黑点,OCR却认成了乱码
前端