【Vue3+TS项目】硅谷甄选day04--顶部组件搭建+面包屑+路由鉴权
顶部组件搭建
顶部左侧折叠和面包屑实现
左侧菜单刷新折叠的问题解决---属性default-active
折叠之后图标不见:icon放在插槽外面----element的menu属性:collapse
project\src\layout\index.vue
// 获取路由对象
import { useRoute } from 'vue-router';
let $route = useRoute()
<el-menu :default-active="$route.path" background-color="$base-menu-background" text-color="white"active-text-color="yellowgreen"><Menu :menuList="userStore.menuRoutes" />
</el-menu>
顶部tabbar静态组件封装:拆分为左侧面包屑、右侧设置区域
面包屑组件:project\src\layout\tabbar\breadcrumb\index.vue
<template><!-- 顶部左侧静态 --><el-icon style="margin-right: 10px;"><Expand /></el-icon><!-- 左侧面包屑 --><el-breadcrumb separator-icon="ArrowRight"><el-breadcrumb-item>权限管理</el-breadcrumb-item><el-breadcrumb-item>用户管理</el-breadcrumb-item></el-breadcrumb>
</template><script setup lang="ts"></script>
<style scoped lang="scss"></style>
右侧设置组件:project\src\layout\tabbar\setting\index.vue
<template><el-button size="small" icon="Refresh" circle /><el-button size="small" icon="FullScreen" circle /><el-button size="small" icon="Setting" circle /><img src="/public/logo.png" style="width: 32px;height: 24px;margin: 0 10px;"><!-- 下拉菜单 --><el-dropdown><span class="el-dropdown-link">Admin<el-icon class="el-icon--right"><arrow-down /></el-icon></span><template #dropdown><el-dropdown-menu><el-dropdown-item>退出登入</el-dropdown-item></el-dropdown-menu></template></el-dropdown>
</template><script setup lang="ts"></script>
<style scoped lang="scss"></style>
project\src\layout\tabbar\index.vue
<template><div class="tabbar"><div class="tabbar_left"><Breadcrumb /></div><div class="tabbar_right"><Setting /></div></div>
</template><script setup lang="ts">
// 引入组件
import Breadcrumb from '@/layout/tabbar/breadcrumb/index.vue'
import Setting from '@/layout/tabbar/setting/index.vue'
</script>
<script lang="ts">
export default {name: "Tabbar"
}
</script>
<style scoped lang="scss">
.tabbar {width: 100%;height: 100%;display: flex;justify-content: space-between;
.tabbar_left {display: flex;align-items: center;margin-left: 20px;
}
.tabbar_right {display: flex;align-items: center;}
}
</style>
菜单折叠的实现
定义控制折叠展开的变量 fold,放在仓库比较合适,因为其他组件也要根据fold进行变化,放在面包屑组件的传递给其他组件比较麻烦
project\src\store\modules\setting.ts
//小仓库:layout组件相关配置仓库
import { defineStore } from 'pinia'
const useLayOutSettingStore = defineStore('SettingStore', {state: () => {return {fold: false, //用户控制菜单折叠还是收起控制}},
})
export default useLayOutSettingStore
面包屑组件:project\src\layout\tabbar\breadcrumb\index.vue(通过点击图标切换仓库中fold的状态,其他组件读取时获取最新的)
// 获取小仓库中的控制折叠展开变量 fold
import useLayOutSettingStore from '@/store/modules/setting';
// 获取仓库
let layOutSettingStore = useLayOutSettingStore()
// 点击折叠展开图标的方法
const changeIcon = () => {layOutSettingStore.fold = !layOutSettingStore.fold
}
<el-icon style="margin-right: 10px;" @click="changeIcon"><!-- vue提供的动态展示组件 --><component :is="layOutSettingStore.fold ? 'Expand' : 'Fold'"></component>
</el-icon>
layout组件读取 fold 变量
project\src\layout\index.vue
// 获取小仓库中的控制折叠展开变量 fold
import useLayOutSettingStore from '@/store/modules/setting';
// 获取仓库
let layOutSettingStore = useLayOutSettingStore()
// :collapse="layOutSettingStore.fold ? true : false"
<el-menu :collapse="layOutSettingStore.fold ? true : false" :default-active="$route.path"background-color="$base-menu-background" active-text-color="yellowgreen"><Menu :menuList="userStore.menuRoutes" />
</el-menu>
//顶部导航和右侧内容展示区域添加动态类fold
:class="{ fold: layOutSettingStore.fold ? true : false }"
Collapse 有点问题,折叠的时候还有bug
顶部面包屑动态展示
通过获取路由匹配信息来实现
layout组件不需要展示到面包屑,直接展示首页,所以去掉layout路由中的元信息title和icon,然后再面包屑渲染时进行v-show判断
点击面包屑也可以进行路由跳转--element可以实现---to
project\src\layout\tabbar\breadcrumb\index.vue
// 获取路由
import { useRoute } from 'vue-router';
let $route = useRoute()
<!-- 左侧面包屑 --><el-breadcrumb separator-icon="ArrowRight"><el-breadcrumb-item v-for="(item, index) in $route.matched" :key="index" v-show="item.meta.title" :to="item.path"><!-- 渲染图标 --><el-icon style="margin: 0 2px;"><component :is="item.meta.icon"></component></el-icon><!-- 渲染面包屑标题 --><span>{{ item.meta.title }}</span></el-breadcrumb-item></el-breadcrumb>
顶部tabbar右侧功能实现
刷新功能实现
简单来说就是路由组件销毁和重建,重新发请求获取数据
涉及顶部导航与内容展示区域间通信---刷新的变量放在小仓库中
小仓库:
refresh: false,//控制刷新效果
setting组件:project\src\layout\tabbar\setting\index.vue
// 获取仓库中的 刷新变量 refresh
import useLayOutSettingStore from '@/store/modules/setting'
let layOutSettingStore = useLayOutSettingStore()
// 点击刷新的回调
const refreshChange = () => {layOutSettingStore.refresh = !layOutSettingStore.refresh
}
//刷新按钮
<el-button size="small" icon="Refresh" circle @click="refreshChange" />
Main组件监听refresh变化,变化就重新发请求
project\src\layout\main\index.vue
import { watch, ref, nextTick } from 'vue'
// 获取仓库中的 刷新变量 refresh
import useLayOutSettingStore from '@/store/modules/setting'
let layOutSettingStore = useLayOutSettingStore()
// 控制组件销毁与创建
let flag = ref(true)
// 监听仓库中的refresh,如果发生变化说明用户点击刷新按钮
watch(() => layOutSettingStore.refresh, () => {//refresh变化,则销毁组件flag.value = false//等待组件完毕重新加载nextTick(() => {flag.value = true})
})
<component :is="Component" v-if="flag" />
全屏功能实现:dom操作
// 点击实现全屏切换
const fullScreen = () => {//DOM对象的一个属性:可以用来判断当前是不是全屏模式[全屏:true,不是全屏:false]let full = document.fullscreenElement;//切换为全屏模式if (!full) {//文档根节点的方法requestFullscreen,实现全屏模式document.documentElement.requestFullscreen();} else {//变为不是全屏模式->退出全屏模式document.exitFullscreen();}
}
<el-button size="small" icon="FullScreen" circle @click="fullScreen" />
退出登入业务
token的理解
登入成功,首页组件挂在完毕,通知用户小仓库拿着token去找服务器那用户的相关数据,并存在小仓库中
home组件:project\src\views\home\index.vue(后面可以在路由守卫中发请求)
import { onMounted } from 'vue';
//引入用户相关的仓库,获取当前用户的头像、昵称
import useUserStore from '@/store/modules/user';
//获取存储用户信息的仓库对象
let userStore = useUserStore();
//首页挂在完毕通知小仓库发请求拿数据
onMounted(() => {userStore.getUserInfo()
})
用户小仓库:project\src\store\modules\user.ts
//记得到type中进行类型定义
username: '',
avatar: ''
// 拿token向服务器请求用户数据
async getUserInfo() {// 获取用户信息进行存储【头像,用户名】let res = await reqUserInfo()if (res.code == 200) {this.username = res.data.checkUser.usernamethis.avatar = res.data.checkUser.avatar} else {}
}
用户有n个请求,那怎么携带token呢,放在请求拦截器里面
project\src\utils\request.ts
// 引入用户相关的仓库
import useUserStore from '@/store/modules/user'
// 第二步:request实例添加请求和响应拦截器
request.interceptors.request.use((config) => {// 获取用户小仓库,拿到登入成功的token数据携带给服务器let userStore = useUserStore()if (userStore.token) {config.headers.token = userStore.token}// config 配置对象,有headers属性请求头,经常给服务器端携带公共参数// 返回配置对象return config;
})
获取到用户信息之后,在tabbar组件的setting组件中展示一下
project\src\layout\tabbar\setting\index.vue
获取仓库,展示即可
退出登入功能实现:点击之后退到登入页,将用户信息和token清除掉
退出登入需要发送请求,告诉服务器token失效,下一次登入服务器重新返回新的token
project\src\layout\tabbar\setting\index.vue
// 退出登入需要进行路由跳转
import { useRouter } from 'vue-router';
// 获取路由器对象
let $router = useRouter()
//退出登录点击回调
const logout = async () => {//第一件事情:需要向服务器发请求[退出登录接口]******暂时没有//第二件事情:仓库当中关于用于相关的数据清空[token|username|avatar]//第三件事情:跳转到登录页面await userStore.userLogout();//跳转到登录页面$router.push({ path: '/login' });
}
<el-dropdown-item @click="logout">退出登入</el-dropdown-item>
用户小仓库:project\src\store\modules\user.ts
//退出登入userLogout() {//目前没有退出接口//清除数据this.token = ''this.username = ''this.avatar = ''localStorage.removeItem('TOKEN')}
还有一些问题需要解决:登入成功之后不允许在跳转到login、用户信息需要持久化存储
路由鉴权与进度条实现
进度条是可以用全局路由守卫实现(前置,后置)
路由组件挂在完毕我们去请求获取用户信息进行展示,但是不适用大量组件,可以通过全局路由守卫进行实现,路由跳转的时候发请求就可以
创建路由鉴权文件
注意:在组件的外部使用小仓库会报错(同步的语句获取仓库不可以),需要获取小仓库的数据必须先有大仓库
发请求:本来我们是在各个组件中发请求获取用户信息,现在我们可以在前置路由守卫中判断有没有用户名,有的话可以放行到其他路由组件,没有的话先获取用户信息再放行
放在路由守卫中也可以解决我们当时在首页中发请求获取用户信息时,我们跳转其他路由组件数据丢失问题,因为路由守卫就算没有用户信息,也会发请求拿到
//获取用户相关的小仓库内部token数据,去判断用户是否登录成功
import useUserStore from './store/modules/user'
import pinia from './store'
const userStore = useUserStore(pinia)
project\src\permisstion.ts//路由鉴权:鉴权,项目当中路由能不能被的权限的设置(某一个路由什么条件下可以访问、什么条件下不可以访问)
import router from '@/router'
import setting from '@/settings'
//@ts-ignore
import nprogress from 'nprogress'
//引入进度条样式
import 'nprogress/nprogress.css'
nprogress.configure({ showSpinner: false })
//获取用户相关的小仓库内部token数据,去判断用户是否登录成功
import useUserStore from './store/modules/user'
import pinia from './store'
const userStore = useUserStore(pinia)
//全局守卫:项目当中任意路由切换都会触发的钩子
//全局前置守卫
router.beforeEach(async (to: any, from: any, next: any) => {//to:你将要访问那个路由//from:你从来个路由而来//next:路由的放行函数nprogress.start()//获取token,去判断用户登录、还是未登录const token = userStore.token//获取用户名字const username = userStore.username//用户登录判断if (token) {//登录成功,访问login,不能访问,指向首页if (to.path == '/login') {next({ path: '/' })} else {//登录成功访问其余六个路由(登录排除)//有用户信息if (username) {//放行next()} else {//如果没有用户信息,在守卫这里发请求获取到了用户信息再放行try {//获取用户信息await userStore.getUserInfo()//放行//万一:刷新的时候是异步路由,有可能获取到用户信息、异步路由还没有加载完毕,出现空白的效果next({ ...to })} catch (error) {//token过期:获取不到用户信息了//用户手动修改本地存储token//退出登录->用户相关的数据清空await userStore.userLogout()next({ path: '/login' })}}}} else {//用户未登录判断if (to.path == '/login') {next()} else {next({ path: '/login' })}}
})
//全局后置守卫
router.afterEach((to: any, from: any) => {document.title = `${setting.title} - ${to.meta.title}`
nprogress.done()
})
//第一个问题:任意路由切换实现进度条业务 ---nprogress
//第二个问题:路由鉴权(路由组件访问权限的设置)
//全部路由组件:登录|404|任意路由|首页|数据大屏|权限管理(三个子路由)|商品管理(四个子路由)
//用户未登录:可以访问login,其余六个路由不能访问(指向login)
//用户登录成功:不可以访问login[指向首页],其余的路由可以访问
在main中引入
//引入路由鉴权文件
import './permisstion'相关文章:
【Vue3+TS项目】硅谷甄选day04--顶部组件搭建+面包屑+路由鉴权
顶部组件搭建 顶部左侧折叠和面包屑实现 左侧菜单刷新折叠的问题解决---属性default-active 折叠之后图标不见:icon放在插槽外面----element的menu属性:collapse project\src\layout\index.vue // 获取路由对象 import { useRoute } from vue-route…...
某oa 11.10 未授权任意文件上传
漏洞简介 之前也对通达 oa 做过比较具体的分析和漏洞挖掘,前几天看到通达 oa 11.10 存在未授权任意文件上传漏洞,于是也打算对此进行复现和分析。 环境搭建 https://www.tongda2000.com/download/p2019.php 下载地址 :https://cdndown.tongda…...
Grounded Language-Image Pre-training(论文翻译)
文章目录 Grounded Language-Image Pre-training摘要1.介绍2.相关工作3.方法3.1统一构建3.2.语言感知深度融合3.3.使用可扩展的语义丰富数据进行预训练 4.迁移到既定的基准4.1.COCO上的zero-shot和监督迁移学习4.2.LVIS上的zero-shot 迁移学习4.3.Flickr30K实体上的 phrase gro…...
设计模式-行为型模式(模板方法、策略、观察者、迭代器、责任链、命令、状态、备忘录、访问者、中介者、解释器)
行为型模式:专注于对象之间的 协作 及如何通过彼此之间的交互来完成任务。行为型模式通常集中在描述对象之间的 责任 分配和 通信 机制,并提供了一些优雅解决特定问题的方案。 模板方法模式(Template Method Pattern)策略模式(Strategy Pattern)观察者模…...
全面探讨 Spring Boot 的自动装配机制
Spring Boot 是一个基于 Spring 框架的快速开发脚手架,它通过自动配置机制帮助我们快速搭建应用程序,从而减少了我们的配置量和开发成本。自动装配是 Spring Boot 的核心特点之一,它可以减少项目的依赖,简化配置文件,提…...
河道水位监测:河道水位监测用什么设备
中国地形复杂,气候多样,导致水资源分布不均,洪涝和干旱等问题时有发生。同时,人类活动也对水资源造成了很大压力,工业和农业用水增加,河道水位下降,生态环境受到威胁。因此,对河道水…...
嵌入式系统中u-boot和bootloader到底有什么区别
嵌入式软件工程师都听说过 u-boot 和 bootloader,但很多工程师依然不知道他们到底是啥。 今天就来简单讲讲 u-boot 和 bootloader 的内容以及区别。 Bootloader Bootloader从字面上来看就是启动加载的意思。用过电脑的都知道,windows开机时会首先加载…...
实验14:20211030 1+X 中级实操考试(id:2498)
实验14:20211030 1X 中级实操考试(id:2498) 一、项目背景说明二、表结构三、步骤【5 分】步骤 1:项目准备【5 分】步骤 2:完成实体类 Member【10 分】步骤 3:完成实体类 Goods【10 分】步骤 4&a…...
(字符串 ) 剑指 Offer 58 - II. 左旋转字符串 ——【Leetcode每日一题】
❓剑指 Offer 58 - II. 左旋转字符串 难度:简单 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的…...
EPICS编程
提纲 1) 为什么在EPICS上编程 2)构建系统特性:假设基本理解Unix Make 3)在libCom中可用的工具 1) 为什么在EPICS上编程 1、社区标准:EPICS合作者知道和明白EPICS结构 2、在很多操作系统之间代码移值性…...
17:00面试,还没10分钟就出来了,问的实在是太...
从外包出来,没想到死在另一家厂子 自从加入这家公司,每天都在加班,钱倒是给的不少,所以也就忍了。没想到8月一纸通知,所有人不许加班,薪资直降30%,顿时有吃不起饭的赶脚。 好在有个兄弟内推我去…...
docker都有那些工具,及工具面试题
docker介绍 Docker 是一种开源的容器化平台,可以帮助开发者将应用程序和依赖项打包到轻量级的容器中,然后部署到任何基于 Linux 的操作系统中。使用 Docker 可以大大简化开发、部署和管理应用程序的过程,使其更加快速、灵活和可靠。 Docker…...
LAMP网站应用架构
LAMP 一、LAMP概述1、各组件的主要作用2、构建LAMP各组件的安装顺序 二、编译安装Apache httpd服务1、关闭防火墙,将安装Apache所需软件包传到/opt目录下2.安装环境依赖包3.配置软件模块4.编译及安装5.优化配置文件路径,并把httpd服务的可执行程序文件放…...
C++虚函数virtual(动态多态)(纯虚函数)
怎么判断函数是虚函数还是普通函数? 用VS,在调用对象的方法的地方。。按altg ,如果他跳转到正确的函数,那也就意味着他是编译时可以确定的。。。 但是如果他跳到了这个调用对象的基类的函数,那么也就意味着他是一个运行…...
【Java 接口】接口(Interface)的定义,implements关键字,接口实现方法案例
博主:_LJaXi Or 東方幻想郷 专栏: Java | 从入门到入坟 专属:六月一日 | 儿童节 Java 接口 接口简介 🎃接口的定义 🧧接口实现类名定义 🎁接口实现类小案例 🎈后话 🎰 接口简介 &…...
解决Vmware上的kali找不到virtualbox上的靶机的问题
解决kali找不到靶场ip问题的完整方法 1.配置靶机2.配置kali的虚拟网络3.配置kali中的eth0网络 1.配置靶机 靶机部署在Virtualbox上对其进行网络配置,选择连接方式为仅主机(Host-Only)网络。 2.配置kali的虚拟网络 在编辑中选择虚拟网络配…...
查看MySQL服务器是否启用了SSL连接,并且查看ssl证书是否存在
文章目录 一、查看MySQL服务器是否启用了SSL连接 1.登录MySQL服务器 2.查看SSL配置 二、查看证书是否存在 前言 查看MySQL服务器是否启用了SSL连接,并且查看ssl证书是否存在 一、查看MySQL服务器是否启用了SSL连接 1.登录MySQL服务器 在Linux终端中…...
华为OD机试真题 Java 实现【表示数字】【牛客练习题】
一、题目描述 将一个字符串中所有的整数前后加上符号“*”,其他字符保持不变。连续的数字视为一个整数。 数据范围:字符串长度满足1≤n≤100 。 二、输入描述 输入一个字符串。 三、输出描述 字符中所有出现的数字前后加上符号“*”,其他字符保持不变。 四、解题思路…...
使用Python进行接口性能测试:从入门到高级
前言: 在今天的网络世界中,接口性能测试越来越重要。良好的接口性能可以确保我们的应用程序可以在各种网络条件下,保持流畅、稳定和高效。Python,作为一种广泛使用的编程语言,为进行接口性能测试提供了强大而灵活的工…...
sed编辑器
文章目录 一.sed命令基础1.sed概念2.sed的工作流程3.命令格式4.sed命令的常用选项5.sed命令的操作符 二.sed命令的打印功能1.打印文本文件内容1.1 格式1.2 默认打印方式 2.指定行打印2.1 指定行号打印2.2 只打印文件的行数2.3 即打印文件的行号也打印文件的内容2.4 即显示行也显…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
