Vue--》Vue3打造可扩展的项目管理系统后台的完整指南(四)

news2024/11/25 6:38:16

今天开始使用 vue3 + ts 搭建一个项目管理的后台,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GithHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏,学习更多前端vue知识,然后开篇先简单介绍一下本项目用到的技术栈都有哪几个方面(阅读本文章能够学习到的技术):

vite:快速轻量且功能丰富的前端构建工具,帮助开发人员更高效构建现代Web应用程序。

pnpm:高性能、轻量级npm替代品,帮助开发人员更加高效地处理应用程序的依赖关系。

Vue3:Vue.js最新版本的用于构建用户界面的渐进式JavaScript框架。

TypeScript:JavaScript的超集,提供了静态类型检查,使得代码更加健壮。

Animate:基于JavaScript的动画框架,它使开发者可以轻松创建各种炫酷的动画效果。

vue-router:Vue.js官方提供的路由管理器与Vue.js紧密耦合,非常方便与Vue.js一同使用。

Pinia:Vue3构建的Vuex替代品,具有响应式能力,提供非常简单的 API,进行状态管理。

element-plus:基于Vue.js 3.0的UI组件库,用于构建高品质的响应式Web应用程序。

axios:基于Promise的HTTP客户端,可以在浏览器和node.js中使用。

three:基于JavaScript的WebGL库,开发者可以编写高性能、高质量的3D场景呈现效果。

echarts:基于JavaScript的可视化图表库,支持多种类型的图表,可根据需要自行安装。

当然还有许多其他的需要安装的第三方库,这里就不再一一介绍了,在项目中用到的地方自行会进行讲解,大家自行学习即可,现在就让我们走进vue3+ts的实战项目吧。

目录

面包屑功能的实现

刷新业务的实现

全屏功能模式的实现

获取用户信息功能的实现

退出登录业务的实现

路由鉴权相关操作

真实接口替换mock接口


面包屑功能的实现

我们在之前编写面包屑组件的时候,是把数据进行写死了,接下来我们想实现的就是如何根据路由的切换动态展现当前的路由标题。我们在面包屑处添加一个button按钮,打印一下当前的路由组件

<button @click="handler">获取到匹配的路由</button>

import { useRoute } from 'vue-router'
// 获取路由对象
const $route = useRoute()
const handler = () => {
  console.log($route)
}

打印出路由的一些重要数据,我们选择我们想要的数据进行处理即可:

通过v-for循环遍历我们想要的数据进行处理:

<!-- 左侧面包屑 -->
<el-breadcrumb separator-icon="ArrowRight">
  <!-- 面包屑动态展示路由名字与标题  -->
  <el-breadcrumb-item
    v-for="(item, index) in $route.matched"
    :key="index"
  >
    <!-- 图标 -->
    <el-icon style="margin: 0 5px">
      <component :is="item.meta.icon"></component>
    </el-icon>
    <!-- 面包屑展示路由的标题 -->
    <span>{{ item.meta.title }}</span>
  </el-breadcrumb-item>
</el-breadcrumb>

准确的来说首页也是二级路由,所以它也会显示两个标题,如下:

但是我们只想显示首页有个标题怎么办,简单只需将首页的父路由标题删掉,然后通过v-show判断即可。这里不能使用v-if,因为优先级比v-for更高:

那么面包屑的路由跳转怎么解决?这里处理的办法就是采用面包屑的to属性:

单极路由不进行跳转,多级路由跳转的话点击只会默认跳转到当前众多子路由的第一个子路由:

最终效果如下:

刷新业务的实现

刷新按钮的功能实现很简单,就是当我们点击刷新按钮的时候,将对应的组件进行销毁然后重新创建,再向服务器去拿数据然后进行展示数据,这样就实现了刷新的功能。因为刷新的功能是子组件向父组件进行请求刷新页面,这里的话我们可以将请求刷新的标识存放到仓库中去:

将数据存放到仓库中后,接下来找到刷新按钮的那个组件,进行刷新标识数据的修改,如下:

在能进行数据的修改之后,接下来可以在路由出口处进行组件动态的销毁与创建从而达到实现刷新页面的效果,这里可以先通过watch监听器监听数据发生变化,然后通过nextTick(用于在 DOM 更新完毕后执行回调函数):

<script setup lang="ts">
import { watch, ref, nextTick } from 'vue'
import useLayOutSettingStore from '@/store/settings'
const layoutSettingStore = useLayOutSettingStore()
// 控制当前组件是否需要进行销毁重建
let flag = ref(true)
// 监听仓库中的数据内容是否发生变化,如果发生变化说明用户点击过刷新按钮
watch(
  () => layoutSettingStore.refsh,
  () => {
    // 点击刷新按钮,路由组件销毁
    flag.value = false
    nextTick(() => {
      flag.value = true
    })
  },
)
</script>

刷新效果如下所示:

全屏功能模式的实现

全屏模式的实现功能很简单,在前端实现全屏模式有几种方法,下面列举其中较为常用的几种:

使用 Fullscreen API:

Fullscreen API 是 HTML5 新增的一种浏览器 API,可以让 Web 应用进入全屏模式。具体使用方式是在要全屏的元素上调用 requestFullscreen() 方法,例如 document.documentElement.requestFullscreen() 将整个文档进入全屏模式。

使用 Webkit/Blink CSS 属性:

Webkit 内核和 Blink 内核的浏览器提供了最简单的全屏实现方式,只需要给想要全屏的元素设置特定的 CSS 属性:-webkit-full-screen 或者 -moz-full-screen。例如:div:-webkit-full-screen { width:100%; height: 100%; }。

使用浏览器全屏插件或扩展程序:

一些浏览器提供了全屏插件或扩展程序,可以为网页提供全屏功能。例如,Chrome 中有一个叫做 Fullscreen Anything 的插件,可以将页面中的任何元素变成全屏模式。

需要注意的是:全屏模式应该谨慎使用,因为它会影响用户体验。如果用户没有明确地请求进入全屏模式,不应该强制将页面进入全屏模式。此外,在某些环境下(例如移动端),用户直接使用操作系统提供的全屏模式可能更为合适,而不是使用前端实现的方式。

我们采用第一种的方式,给tabbar组件中的切换全屏按钮设置点击事件,如下:

// 切换全面模式展现
const fullScreen = () => {
  // DOM对象的有个属性,用来判断当前是不是全屏模式[全屏:true,不是全屏:null]
  let full = document.fullscreenElement
  // 切换全屏模式
  if (!full) {
    // 文档根节点的方法requestFullscreen,实现全屏模式
    document.documentElement.requestFullscreen()
  } else {
    // 退出全屏模式
    document.exitFullscreen()
  }
}

功能实现结果如下:

全屏功能后面的设置按钮是对整个页面的主题颜色的设置,这里的话因为整体页面还没有搭建完成,所以这个功能点会放到后期讲解。

获取用户信息功能的实现

获取用户信息的功能我们在之前的API中已经给出了相关的调用函数,如下:

接下来我们在user仓库中进行引入该函数:

因为token在很多项目中都是公共参数,在登录项目中所有的请求,必须把token带上,意思就是说我们在登录成功之后,只要是发起请求就得把token带上,所以我们必须在请求拦截器处进行token的绑定。

处理完成之后,我们就可以在登录成功之后获取登录的相关信息并将部分数据进行展示:

我们在登录完成之后,在首页进行数据的挂载

最后结果如下:

退出登录业务的实现

我们在tabbar组件的退出登录按钮设置点击事件,进行退出登录时相关数据清楚的操作,如下:

清楚数据完成之后,接下来我们需要在login登录组件进行相关的判断,这里我们增加的需求就是,如果用户退出登录后是会保留其当前退出登录的路由路径的的,并以query的方式返回给登录页面,这样一旦跳转到登录页面后再进行登录,登录之后的页面就是我们之前退出离开的页面不再是默认的home页面了,如下:

路由鉴权相关操作

我们在之前的文章就讲解过路由鉴权的操作,当然也手写了一份进度条的案例样式,但是不是很正规,接下来我们将我们进行路由鉴权的操作抽离出来封装成一个ts文件,然后再入口文件 main.ts 处进行引入。

因为我们之前手写过进度条业务,所以接下来我们可以使用npm包来进行实现,其官方文档为:网址 ,我们执行如下命令下载第三方包:

pnpm i nprogress

其官方文档也给出了我们使用该插件的方法,比我们自己封装快多了:

我们将之前在main.ts中的路由导航守卫注释掉,然后在当前的文件中进行书写相关的代码文件:

// 路由鉴权文件
import router from '@/router'
// 引入进度条插件
import nprogress from 'nprogress'
// 引入进度条样式
import 'nprogress/nprogress.css'

// 全局前置守卫(项目中任意路由的切换都会触发的钩子)
router.beforeEach((to: any, from: any, next: any) => {
  nprogress.start()
  next()
})

// 全局后置守卫
router.afterEach((to: any, from: any) => {
  nprogress.done()
})

接下来我们将我们原本在入口文件写的路由导航守卫的操作,移植到该文件处:

// 路由鉴权文件
import router from '@/router'
// 引入进度条插件
import nprogress from 'nprogress'
// 引入进度条样式
import 'nprogress/nprogress.css'
// 取消加载的小圆球
nprogress.configure({ showSpinner: false })

// 获取用户相关信息数据的仓库,去判断用户是否登录
import useUserStore from '@/store/user'
import pinia from '@/store'
const userStore = useUserStore(pinia)
// 全局前置守卫(项目中任意路由的切换都会触发的钩子)
router.beforeEach(async (to: any, from: any, next: any) => {
  nprogress.start()
  // 获取token,去判断用户是否登录
  const token = userStore.token
  // 获取用户名字
  const username = userStore.username
  if (token) {
    // 用户登录判断
    // 用户登录成功如果想去访问登录页面,我们是不能让你访问的直接跳转到首页
    if (to.path == '/login') {
      next({ path: '/' })
    } else {
      if (username) {
        // 放行
        next()
      } else {
        // 如果没有用户信息,在守卫这里发请求获取到用户信息再放行
        try {
          // 获取用户信息成功后放行
          await userStore.useInfo()
          next()
        } catch (error) {
          // 两种情况:token过期获取不到用户信息;用户手动修改了本地存储的token
          userStore.userLogout()
          next({ path: '/login', query: { redirect: to.path } })
        }
      }
    }
  } else {
    // 用户未登录判断
    if (to.path == '/login') {
      next()
    } else {
      next({ path: '/login' })
    }
  }
})

// 全局后置守卫
router.afterEach((to: any, from: any) => {
  // 设置标题
  document.title = to.meta.title
  nprogress.done()
})

真实接口替换mock接口

我们之前讲解的登录退出获取用户信息等接口,仅仅是模拟数据的接口,真实项目中还是需要借助真实的后端编写的接口给我们,因为后面会真正涉及到一些和后端数据库交互的功能,这里还是需要我们使用真实接口的,接下来我们将配置好真实接口数据来替换mock接口。

loadEnv 是一个在 Vue.js 项目中用于加载环境变量配置的函数,通常在项目启动时进行调用。它会根据当前环境读取不同的配置文件,并将配置信息挂载到 process.env 对象上,以便其他模块可以访问和使用。

使用 loadEnv 函数可以让我们方便地切换环境,并且可以避免在代码中暴露敏感信息。同时,也可以通过不同的环境配置文件来管理不同环境下的变量值,提高项目的可维护性和扩展性。

注意:我们在使用真实接口的时候可能与我们模拟的接口数据有相关出入的地方,这里的话需要我们进行相关的排查然后进行相关的修改,(具体操作就不再赘述)如下:

设置完成之后,我们在api下处理用户信息的user接口文件中进行相关修改:

// 统一管理我们项目用户的相关接口
import requset from '@/utils/request'
// 约束ts类型
import type {
  loginFormData,
  loginResponseData,
  userInfoReponseData,
} from './type'
// 统一管理接口
enum API {
  LOGIN_URL = '/admin/acl/index/login',
  USERINFO_URL = '/admin/acl/index/info',
  LOGOUT_URL = '/admin/acl/index/logout',
}
// 暴露请求函数
// 登录接口的方法
export const reqLogin = (data: loginFormData) =>
  requset.post<any, loginResponseData>(API.LOGIN_URL, data)
// 获取用户信息接口方法
export const reqUserInfo = () =>
  requset.get<any, userInfoReponseData>(API.USERINFO_URL)
// 退出登录
export const reqLogout = () => requset.post<any, any>(API.LOGOUT_URL)

设置约束ts文件:

// 定义用户相关数据的ts类型
// 用户登录接口携带参数的ts类型
export interface loginFormData {
  username: string
  password: string
}

// 定义全部接口返回数据都拥有的ts类型
export interface ResponseData {
  code: number
  message: string
  ok: boolean
}

// 定义登录接口返回数据类型
export interface loginResponseData extends ResponseData {
  data: string
}

//定义获取用户信息返回数据类型
export interface userInfoReponseData extends ResponseData {
  data: {
    routes: string[]
    buttons: string[]
    roles: string[]
    name: string
    avatar: string
  }
}

然后在在仓库中进行更新完善即可:

本项目的tabbar页面功能的搭建就讲解到这,下一篇文章将讲解main主体内容,关注博主学习更多前端vue知识,您的支持就是博主创作的最大动力!  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/608830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

保姆级别ps bate版本下载

前言&#xff1a;最近的ps bete版本在抖音也是上了热搜&#xff0c;时不时就能刷到一个&#xff0c;相信大家也知道ai带来的魅力&#xff0c;真的很强&#xff0c;那我们就开始安装教程吧。 ​过程&#xff1a; 先打开链接&#xff1a;Adobe Creative Cloud | Details and pr…

使用外部工具横向移动

Smbexe、Psexec Psexec PsExec是一种轻巧的telnet代替品&#xff0c;可让您在其他系统上执行进程&#xff0c;并为控制台应用提供完整的交互性&#xff0c;无需手动安装客户端软件。 原理&#xff1a; 1、ipc$连接&#xff0c;释放Psexesvc.exe 2、OpenSCManager打开受害者…

如何使用ChatGPT自带插件

OpenAI的插件将ChatGPT连接到第三方应用程序。这些插件使ChatGPT能够与开发者定义的API进行交互&#xff0c;增强ChatGPT的能力&#xff0c;并使其能够执行广泛的操作。插件使ChatGPT能够做如下事情&#xff1a; 获取实时信息&#xff1b;例如&#xff0c;体育比分&#xff0c…

采样率(压缩比)对OMP算法的影响

前面详细分析了OMP重构算法原理以及实现&#xff0c;本篇主要分析采样率对OMP算法的影响。 OMP重构算法的流程为 以下分析采样率对OMP算法的影响。 先对一维信号重构进行分析&#xff0c;表1是OMP算法中采样率对重构的MSE和时间的对应表格&#xff1a; 表1&#xff1a;MP算法采…

04-Springbooot与Spring Cloud Alibaba搭建后端架构

1、创建Springbooot父工程 1.1、使用快速创建Springbooot工程的方式&#xff1a; 1.2、项目使用Maven进行管理 settings.xml&#xff0c;配好了阿里镜像 02-maven的安装配置_NikoWord的博客-CSDN博客 2、项目初始化配置 01-IDEA使用技巧_NikoWord的博客-CSDN博客 04-设置…

VS2010 C语言DLL项目hello world程序以及win32控制台程序调用dll示例

一、使用Visual Studio 2010编写C语言 DLL项目hello world程序 1.点击桌面 VS2010 图标&#xff0c;运行程序。(或者通过菜单栏打开程序) 2.点击【文件】 -> 【新建】 -> 【项目】 3.点击【VisualC】和【win32控制台应用程序】&#xff0c;设置好名称和存储位置&#xf…

白盒测试方法

为什么要进行白盒测试&#xff1f; 如果所有软件错误的根源都可以追溯到某个唯一原因&#xff0c;那么问题就简单了。然而&#xff0c;事实上一个bug 常常是由多个因素共同导致的&#xff0c;如下图所示。 黑盒查不到的问题 假设此时开发工作已结束&#xff0c;程序送交到测试…

飞腾FT2000实战开发-GPIO的配置

目录 环境&#xff1a; 飞腾GPIO介绍&#xff1a; 临时配置&#xff1a; 永久配置&#xff1a; 环境&#xff1a; CPU:FT2000&#xff08;64位&#xff0c;四核&#xff09; 操作系统&#xff1a;linux-4.4.131-20200710 内核&#xff1a;kylin4.0.2 飞腾GPIO介绍&#x…

JavaScript创建二维数组踩坑记录

需求&#xff1a;创建一个m*n且元素值为0的二维数组 碎碎念 1、 今天刷Leetcode时&#xff0c;遇见一个这样的需求&#xff0c;机智如我&#xff0c;定然不会通过双重for循环来创建&#xff0c;于是&#xff0c;我写了这样一行代码 const dimensionalArray new Array(m).fi…

Spring Boot 加载自定义配置文件

文章目录 一、为什么需要加载自定义配置文件二、使用PropertySource加载自定义配置文件&#xff08;一&#xff09;创建Spring Boot项目&#xff08;二&#xff09;创建自定义配置文件&#xff08;三&#xff09;创建自定义配置类&#xff08;四&#xff09;编写测试方法&#…

硅谷甄选 Blog_01-搭建后台管理系统模板

搭建后台管理系统模板分为两大步骤&#xff1a; 项目初始化项目配置 项目初始化 环境准备 node&#xff1a;v16.16.0pnpm&#xff1a;v7.22.0 初始化项目 全局安装pnpm指令&#xff1a; npm i -g pnpm项目初始化指令&#xff1a; pnpm create vite如下图所示进行项目的…

嵌入式BSP工程师基本任务分析

到底什么是BSP工程师呢&#xff1f;来看这篇文章吧 一、嵌入式系统 要明白什么是嵌入式软件工程师&#xff0c;我们先从嵌入式系统&#xff08;嵌入式设备&#xff09;说起。维基百科上对嵌入式系统的定义如下&#xff1a; 嵌入式系统&#xff08;Embedded System&#xff0…

5 个强大的 HTML5 API

HTML5提供了一些非常强大的JavaScript和HTML API&#xff0c;来帮助开发者构建精彩的桌面和移动应用程序。本文将介绍5个新型的API&#xff0c;希望对你的开发工作有所帮助。 1. 全屏API&#xff08;Fullscreen API&#xff09; 该API允许开发者以编程方式将Web应用程序全屏运…

1_标准IO

目录 标准I/O一、概念二、特点⭐⭐⭐三、缓冲区⭐⭐⭐3.1 全缓冲3.1 行缓冲3.3 不缓冲 四、函数接口⭐⭐⭐⭐4.1 打开4.1.1 fopen4.1.2 freopen4.1.2 容错机制perror 4.2 关闭4.2.1 fclose4.3 读写操作4.3.1 字符I/O4.3.2 行I/O4.3.3 块I/O 4.4 定位操作4.5 文件结束和错误 标准…

多维时序 | MATLAB实现NARX非线性自回归外生模型多变量多步时间序列预测(电池预测模型)

多维时序 | MATLAB实现NARX非线性自回归外生模型多变量多步时间序列预测(电池预测模型) 目录 多维时序 | MATLAB实现NARX非线性自回归外生模型多变量多步时间序列预测(电池预测模型)效果一览基本介绍模型描述程序设计参考资料效果一览 基本介绍 多维时序 | MATLAB实现NARX非…

CSDN 周赛 56 期

CSDN 周赛 56 期 1、题目名称&#xff1a;因数-数字游戏骗分抛出异常考试时代码 2、题目名称&#xff1a;津津的储蓄计划3、题目名称&#xff1a;一维数组的最大子数组和4、题目名称&#xff1a;莫名其妙的键盘小结 1、题目名称&#xff1a;因数-数字游戏 小Q的柠檬汁做完了。 …

为视图增加权重以调整基本线性布局

乍看上去线性布局LinearLayout很基础&#xff0c;不太灵活&#xff0c;毕竟其只是按照某种顺序摆放视图。但是还可以使用另外一些属性调整布局的外观。 编写一个不太一样的布局。这个布局让按钮显示在布局的右下角&#xff0c;其余全部空间由一个可编辑文本域占据。 一个基本线…

算法套路十九——树形DP

算法套路十九——树形DP 树形 DP&#xff0c;即在树上进行的 DP。由于树固有的递归性质&#xff0c;这里的DP是指是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法&#xff0c;故虽然带有DP&#xff0c;但一般都是通过递归来进行。 算法示例一&#xff1a;…

centos7使用docker compose部署ELK

说明&#xff1a;1、一定要先不要配置那么多配置文件&#xff0c;去除掉一些&#xff0c;先让docker compose启动相关服务能访问的时候&#xff0c;使用拷贝方法&#xff0c;把相关的配置文件拷贝出来在外面修改&#xff0c;这样保险一些&#xff0c;不然容易配置文件错误无法启…

90.构建 “工作流程 “第一部分

记得我们上次实现的页面的了么&#xff0c;如下图所示&#xff0c;这节我们接着来 记住我们之前的画的草图 现在我们就来构建Z字形的工作流程部分&#xff1b; ● 首先我们添加标题 工作流程 3个简单的步骤制作您每天的健康饮食 ● 接着就是添加Z字形的工作步骤 <div cl…