vue3-11

后端Java代码 

src\router\a6router.ts文件

import { createRouter, createWebHashHistory } from 'vue-router'
import { useStorage } from '@vueuse/core'
import { Menu, Route } from '../model/Model8080'
const clientRoutes = [
    {
        path: '/login',
        name: 'login',
        component: () => import('../views/A6Login.vue')
    },
    {
        path: '/404',
        name: '404',
        component: () => import('../views/A6NotFound.vue')
    }, {
        path: '/',
        name: 'main',
        component: () => import('../views/A6Main.vue')
    }, {
        path: '/:pathMatcher(.*)*',
        name: 'remaining',
        redirect: '/404'
    }
]
const router = createRouter({
    history: createWebHashHistory(),
    routes: clientRoutes
})
//在每次路由跳转之前都会执行beforeEach里面的箭头函数,to代表要跳转的目标路由对象,from代表源路由对象
router.beforeEach((to,from)=>{
  if(to.name ==='main' && !serverToken.value){
        return '/login'
  }
})
//修改页面标题
router.afterEach((to,from)=>{
document.title = to.name?.toString() || ''
})
const serverRoutes = useStorage<Route[]>('serverRoutes', [])
export const serverMenus = useStorage<Menu[]>('serverMenus',[])
//把从后端返回的token中的用户名存储起来
export const serverUsername = useStorage<string>('serverUsername','')
//把从后端返回的token存储起来
export const serverToken = useStorage<string>('serverToken','')
addServerRoutes(serverRoutes.value)
export function addServerRoutes(routeList: Route[]) {
    for (const r of routeList) {
        // r.parentName:是加入的路由的父路由,是addRoute()需要的参数
        router.addRoute(r.parentName, {
            path: r.path,
            name: r.name,
            component: () => import(r.component)
        })
    }
    serverRoutes.value = routeList
}

export function resetRoutes() {
    for (const r of clientRoutes) {
        router.addRoute(r)
    }
    serverRoutes.value= null
    serverMenus.value = null
    serverToken.value = null
    serverUsername.value = null
}
export default router

src\views\A6Login.vue文件

<template>
  <div class="login">
    <a-form :label-col="{ span: 6 }" autocomplete="off">
      <a-form-item label="用户名" v-bind="validateInfos.username">
        <a-input v-model:value="dto.username" />
      </a-form-item>
      <a-form-item label="密码" v-bind="validateInfos.password">
        <a-input-password v-model:value="dto.password" />
      </a-form-item>
      <a-form-item :wrapper-col="{ offset: 6, span: 16 }">
        <a-button type="primary" @click="onClick">登录</a-button>
      </a-form-item>
    </a-form>
  </div>
</template>
<script setup lang="ts">
import { onMounted, ref} from 'vue'
import { Form } from 'ant-design-vue'
import { addServerRoutes ,resetRoutes,serverMenus,serverToken,serverUsername} from '../router/a6router'
import _axios from '../api/request'
import { useRequest } from 'vue-request'
import { AxiosRespToken, LoginDto, AxiosRespMenuAndRoute } from '../model/Model8080'
import { useRouter } from 'vue-router'
const router = useRouter()
const dto = ref({ username: '', password: '' })
const rules = ref({
  username: [
    { required: true, message: '用户名必填' }
  ],
  password: [
    { required: true, message: '密码必填' }
  ]
})
const { validateInfos, validate } = Form.useForm(dto, rules)
const { runAsync: login } = useRequest<AxiosRespToken, LoginDto[]>((dto) => _axios.post('/api/loginJwt', dto), { manual: true })
const { runAsync: menu } = useRequest<AxiosRespMenuAndRoute, string[]>((username) => _axios.get(`/api/menu/${username}`), { manual: true })
async function onClick() {
  try {
    await validate()
  
    const loginResp = await login(dto.value)
    if (loginResp.data.code === 200) {
      resetRoutes()
      const token = loginResp.data.data.token
      console.log(token)
      serverToken.value= token
      serverUsername.value = getUsername(token)
      const menuResp = await menu(serverUsername.value)
      serverMenus.value =menuResp.data.data.menuTree
      console.log(menuResp.data.data.routeList)
      addServerRoutes(menuResp.data.data.routeList)
      router.push('/')
    }
  } catch (error) {
    console.error(error)
  }
}
function getUsername(token:string){
  if(!token){
    return ''
  }
  const s = token.split('.')
  return JSON.parse(atob(s[1])).sub
}
onMounted(()=>{
  resetRoutes()
})
</script>
<style scoped>
.login {
  margin: 200px auto;
  width: 300px;
  padding: 20px;
  height: 180px;
  background-color: antiquewhite;
}
</style>

src\views\A6Main.vue文件

<template>
  <div class="a6main">
    <a-layout>
      <a-layout-header>

        <span>{{ serverUsername }} 【{{ UserInfo.name }} -{{ UserInfo.sex }}】</span>
      </a-layout-header>
      <a-layout>
      <a-layout-sider>
        <a-menu theme="dark" mode="inline">
          <template v-for="m1 of serverMenus">
            <a-sub-menu v-if="m1.children" :key="m1.id" :title="m1.title">
              
             <template #icon><a-icon :icon="m1.icon"></a-icon></template>
              
              <a-menu-item v-for="m2 of m1.children" :key="m2.id">
               
                <template #icon>   <a-icon :icon="m2.icon"></a-icon>  </template>
              
                <router-link v-if="m2.routePath" :to="m2.routePath">{{ m2.title }}</router-link>
                <span v-else>{{ m2.title }}</span>
              </a-menu-item>
            </a-sub-menu>
            <a-menu-item v-else :key="m1.id">
              
               <template #icon> <a-icon :icon="m1.icon"></a-icon></template>
              
              <router-link v-if="m1.routePath" :to="m1.routePath">{{ m1.title }}</router-link>
              <span v-else>{{ m1.title }}</span>
            </a-menu-item>
          </template>
        </a-menu>
      </a-layout-sider>
      <a-layout-content>
        <router-view></router-view>
      </a-layout-content>
    </a-layout>
    </a-layout>
  </div>
</template>
<script setup lang="ts">
import { serverMenus,serverUsername } from '../router/a6router'
import AIcon from '../components/AIcon3';
import {useUserInfo} from '../store/UserInfo'
import { onMounted } from 'vue';
const UserInfo = useUserInfo()

onMounted(()=>{
  UserInfo.get(serverUsername.value)
})
</script>
<style scoped>
.a6main {
  height: 100%;
  background-color: rgb(220, 225, 255);
  box-sizing: border-box;
}

.ant-layout-header {
  height: 50px;
  background-color: gold;
  border-bottom: 1px solid black;
  padding: 0 25px 0 0;
  line-height: 50px;
  text-align: right;
}

.ant-layout-sider {
  background-color: gold;
  border-right: 1px solid black;
}

.ant-layout-content {
  background-color: gold;
}

.ant-layout-footer {
  background-color: darkslateblue;
  height: 30px;
}

.ant-layout {
  height: 100%;
}

.ant-layout-has-sider {
  height: calc(100% - 50px);
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

odoo17 | 开发环境设置

前言 开始odoo17开发之前&#xff0c;请先掌握python的基本语法和工具包的使用&#xff0c;以及postgres数据库的安装&#xff0c;和简单的sql使用。以及一些前端的html、css、javascript等前端知识&#xff0c;以及xml、json等数据传输的使用。 本教程同时适用于odoo15-17 …

[ffmpeg系列 02] 音视频基本知识

一 视频 RGB&#xff1a;rgb24, AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB… Y&#xff1a;明亮度, Luminance或luma, 灰阶图&#xff0c; UV&#xff1a;色度&#xff0c;Chrominance或Chroma。 YCbCr: Cb蓝色分量&#xff0c;Cr是红色分量。 取值范围&am…

【LMM 001】大型语言和视觉助手 LLaVA

论文标题&#xff1a;Visual Instruction Tuning 论文作者&#xff1a;Haotian Liu, Chunyuan Li, Qingyang Wu, Yong Jae Lee 作者单位&#xff1a;University of Wisconsin-Madison, Microsoft Research, Columbia University 论文原文&#xff1a;https://arxiv.org/abs/230…

【力扣题解】P530-二叉搜索树的最小绝对差-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P530-二叉搜索树的最小绝对差-Java题解&#x1f30f;题目描述&#x1f4a1;题解&…

Casper Network 推出 “DevRewards” 计划:允许所有开发者赚取激励

Casper Association 是一个致力于推动区块链大规模采用的非营利组织&#xff0c;该组织在 Casper Network 系统中推出了一个被称为 “DevRewards ” 的奖励计划&#xff0c;旨在邀请开发者提交能够解决现有问题的创新技术方案&#xff0c;以帮助 Casper Network 系统进一步完善…

modelsim安装使用

目录 modelsim 简介 modelsim 简介 ModelSim 是三大仿真器公司之一mentor的产品&#xff0c;他可以模拟行为、RTL 和门级代码 - 通过独立于平台的编译提高设计质量和调试效率。单内核模拟器技术可在一种设计中透明地混合 VHDL 和 Verilog&#xff0c;常用在fpga 的仿真中。 #…

初探Listener内存马

Listener基础 配置Listener . xml配置 流程分析 读取配置文件 读取web.xml&#xff0c;处理后将信息存储在webXml中 配置context 直接遍历并添加至addApplication中 以上步骤就是将webxml中的listener相关的数据添加到ApplicationListener 接下来直接跟进到listenerStart …

【VRTK】【VR开发】【Unity】18-VRTK与Unity UI控制的融合使用

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【背景】 VRTK和Unity自身的UI控制包可以配合使用发挥效果。本篇就讨论这方面的实战内容。 之前可以互动的立体UI并不是传统的2D UI对象,在实际使用中…

主成分分析(PCA):探索数据的核心

文章目录 前言1. 什么是 PCA &#xff1f;2. PCA 的原理2.1 协方差和方差2.2 核心思想2.3 步骤 3. PCA 的应用场景4. PCA 的优缺点5. 示例&#xff1a;人脸识别5.1 完整代码5.2 运行结果 结语 前言 当今社会&#xff0c;数据无处不在。从社交媒体到金融交易&#xff0c;从医疗…

SpringBoot解决跨域的5种方式

本文来说下SpringBoot中实现跨域的5种方式。 文章目录 什么是跨域java解决CORS跨域请求的方式 返回新的CorsFilter(全局跨域)重写WebMvcConfigurer(全局跨域)使用注解 (局部跨域)手动设置响应头(局部跨域)使用自定义filter实现跨域 本文小结 什么是跨域 跨域&#xff1a;指的…

在FC中手工创建虚拟机模板

1、Linux去除个性化信息 &#xff08;1&#xff09;编辑网卡配置文件&#xff0c;只保留以下内容&#xff08;以RHEL 7为例&#xff09; &#xff08;2&#xff09;清除主机密钥信息&#xff08;开机会自动生成&#xff09; &#xff08;3&#xff09;清除Machine ID&#xff…

Java智慧工地管理平台系统源码带APP端源码

智慧工地将“互联网”的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度地收集人员、安全、环境、材料等关键业务数据&#xff0c;依托物联网、互联网&#xff0c;建立云端大数据管理平台&#xff0c;形成“端云大数据”的业务体系和新的管理模式&a…

JAVA反序列化之URLDNS链分析

简单介绍下urldns链 在此之前最好有如下知识&#xff0c;请自行bing or google学习。 什么是序列化 反序列化 &#xff1f;特点&#xff01; java对象反射调用&#xff1f; hashmap在java中是一种怎样的数据类型&#xff1f; dns解析记录有那…

Phind-CodeLlama-34B-v2 + Excel + Python 超强组合玩转数据分析

Phind-CodeLlama-34B-v2 Excel Python 超强组合玩转数据分析 0. 背景1. 使用 Phind-CodeLlama-34B-v2 pandas 实现数据导入和导出1.1 使用 Phind-CodeLlama-34B-v2 pandas 导入 Excel 文件中的数据1.2 使用 Phind-CodeLlama-34B-v2 pandas 读取部分Excel文件数据 2. 使用 …

Origin 2021软件安装包下载及安装教程

Origin 2021下载链接&#xff1a;https://docs.qq.com/doc/DUnJNb3p4VWJtUUhP 1.选中下载的压缩包&#xff0c;然后鼠标右键选择解压到"Origin 2021"文件夹 2.双击打开“Setup”文件夹 3.选中“Setup.exe”鼠标右键点击“以管理员身份运行” 4.点击“下一步" 5…

C ++类

定义一个Person类&#xff0c;私有成员int age&#xff0c;string &name&#xff0c;定义一个Stu类&#xff0c;包含私有成员double *score&#xff0c;写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数&#xff0c;完成对Person的运算符重载(算术运算符、条件运算…

每个AI/ML工程师必须了解的人工智能框架和工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【SpringCloud Alibaba笔记】(2)Nacos服务注册与配置中心

Nacos Nacos简介与下载 是什么&#xff1f; 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;就是注册中心&#xff0b;配置中心的组合 Nacos Eureka Config Bus 替代Eureka…

vscode配置的C++环境

目录 1、下载并安装VScode 2、下载MinGW 3、配置MinGW 3.1添加环境变量 3.2 Vscode配置 3.3测试 1、下载并安装VScode Visual Studio Code - Code Editing. Redefined 2、下载MinGW 在MinGW官网MinGW-w64 - for 32 and 64 bit Windows - Browse /mingw-w64/mingw-w64-r…

OpenOCD简介和下载安装(Ubuntu)

文章目录 OpenOCD简介OpenOCD软件模块OpenOCD源码下载OpenOCD安装 OpenOCD简介 OpenOCD&#xff08;Open On-Chip Debugger&#xff09;开放式片上调试器 OpenOCD官网 https://openocd.org/&#xff0c;进入官网点击 About 可以看到OpenOCD最初的设计是由国外一个叫Dominic Ra…