vue3-11

发布时间:2023年12月28日

后端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>

文章来源:https://blog.csdn.net/weixin_44478828/article/details/135268883
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。