项目基本架构跟 vite实现element-plus按需配置,自定义主题和读取/修改系统主题色 相同。项目地址。
目标:在vite-plugin-pages 自动读取文件夹配置下,设置前端路由权限和单组件权限。
权限模块后台返回数据假设:返回 与前端文件夹匹配的路径数据,并包含权限信息。
假设,无权限数据为:
{
"code": 200,
"data": [
{
"menu": [
{
"label": "面板1",
"key": "index",
"meta": {
"isAdmin": false,
"requiresAuth": false
}
},
{
"label": "统计分析",
"key": "index-analysis",
"meta": {
"isAdmin": true,
"requiresAuth": false
}
},
{
"label": "编辑器",
"key": "index-editor",
"meta": {
"isAdmin": false,
"requiresAuth": false
}
},
{
"label": "权限管理",
"key": "index-permission",
"meta": {
"isAdmin": false,
"requiresAuth": true
}
},
{
"label": "关注",
"key": "attention",
"meta": {
"isAdmin": false,
"requiresAuth": false
}
}
]
}
]
}
有权限数据为:
......
{
"label": "权限管理",
"key": "index-permission",
"meta": {
"isAdmin": true,
.....
}
},
......
实现功能:判断当前用户是否为管理员,如果不是,切换为管理员。
<template>
<div class="index-permission w-full overflow-hidden bg-slate-100 p-4">
<p v-if="route.meta.isAdmin">当前是admin用户</p>
<p v-else>当前不是admin用户</p>
<el-button v-if="!route.meta.isAdmin" type="primary" size="default" @click="changeMenu">切换为admin用户</el-button>
</div>
</template>
<script setup lang="ts">
import { handleRouterMeta } from '@/router';
import { useMenuStore } from '@/stores/menu';
let route = useRoute()
const { changeMenus, sideMenusFlat } = useMenuStore()
const changeMenu = async () => {
await changeMenus()
handleRouterMeta(sideMenusFlat);
location.reload()
}
</script>
View Code方案:使用router的beforeEach对路由进行修改。
import {IMenuItem} from "@/models/menu";
import {useMenuStore} from "./stores/menu";
import {createWebHistory, createRouter, RouteMeta} from "vue-router";
import routes from "~pages";
import "vue-router";
declare module "vue-router" {
interface RouteMeta {
// 是可选的
isAdmin?: boolean;
// 每个路由都必须声明
requiresAuth: boolean;
}
}
export const router = createRouter({
history: createWebHistory("/"),
routes,
});
export const handleRouterMeta = (sideMenusFlat: IMenuItem[]) => {
let routesFlat = router.getRoutes();
sideMenusFlat.forEach((curRoute) => {
let match = routesFlat.find((i) => i.name == curRoute.key);
if (match) {
match.meta = curRoute.meta as RouteMeta;
}
});
};
let isFresh = true; //刷新页面重新处理路由
router.beforeEach(async (to, _, next) => {
if (to.path === "/login") {
next();
return;
}
const {sideMenus, getMenus, sideMenusFlat} = useMenuStore();
if (isFresh && sideMenus.length) {
isFresh = false;
handleRouterMeta(sideMenusFlat);
next({...to});
return;
}
if (sideMenus.length === 0) {
isFresh = false;
await getMenus();
handleRouterMeta(sideMenusFlat);
next({...to});
} else {
isFresh = false;
handleRouterMeta(sideMenusFlat);
next();
}
});
这里我把路由和导航的处理放在了一起 menu.Store.ts
import {IMenuItem} from "@/models/menu";
import {IMenu} from "@/models/menu";
import {defineStore} from "pinia";
import {useSideMenu1, useSideMenu2} from "@/utils/api";
export const useMenuStore = defineStore(
"menu",
() => {
let sideMenus = ref<IMenu[]>([]);
let sideMenusFlat = ref<IMenuItem[]>([]);
const flatMenu = (menus: IMenu[]) => {
menus.forEach((m: any) => {
m.menu ? flatMenu(m.menu) : sideMenusFlat.value.push(m);
});
};
const getMenus = async () => {
const {code, data} = await useSideMenu1();
if (code === 200) {
sideMenus.value = data;
flatMenu(sideMenus.value);
return;
}
};
const changeMenus = async () => {
sideMenus.value = [];
const {code, data} = await useSideMenu2();
if (code === 200) {
sideMenus.value = data;
flatMenu(sideMenus.value);
return;
}
};
return {
getMenus,
sideMenus,
sideMenusFlat,
changeMenus,
};
},
{
persist: {
paths: ["sideMenus", "sideMenusFlat"],
},
}
);
View Code页面示例:
<template>
<div class="index-permission w-full overflow-hidden bg-slate-100 p-4">
<p v-if="route.meta.isAdmin">当前是admin用户</p>
<p v-else>当前不是admin用户</p>
<el-button v-if="!route.meta.isAdmin" type="primary" size="default" @click="changeMenu">切换为admin用户</el-button>
</div>
</template>
<script setup lang="ts">
import { handleRouterMeta } from '@/router';
import { useMenuStore } from '@/stores/menu';
let route = useRoute()
const { changeMenus, sideMenusFlat } = useMenuStore()
const changeMenu = async () => {
await changeMenus()
handleRouterMeta(sideMenusFlat);
location.reload()
}
</script>
单组件权限
app.directive("permission", (el, binding) => {
const permission = binding.value;
let routeMeta = router.currentRoute.value.meta;
if (routeMeta[permission]) {
el.style.display = "block";
} else {
el.style.display = "none";
}
});
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。