mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-11-03 13:44:47 +08:00
Compare commits
4 Commits
880963c683
...
v6.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0fd7419c5 | ||
|
|
6b179e6ff1 | ||
|
|
e1fde7d386 | ||
|
|
fc30039a40 |
@@ -1,3 +1,23 @@
|
|||||||
|
# 6.2.0 (2025-10-16)
|
||||||
|
|
||||||
|
### 🎫 Features
|
||||||
|
|
||||||
|
- Added full-screen `403`, `404`, and `500` error pages. These full-screen error pages are clear and secure, improving the user experience.
|
||||||
|
|
||||||
|
### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Fixed an issue where the built-in homepage did not have a `name` configured, causing cache invalidation after setting the page cache.
|
||||||
|
- Fixed an issue where, in an embedded same-origin `iframe` page, when the `beforeunload` event was registered, right-clicking a tab and reloading it would cause the browser to prompt two confirmation blocks.
|
||||||
|
- Fixed an issue where pages with `keepAlive: true` set to cache invalidation when the initial load was slow.
|
||||||
|
- Fixed an issue where multiple tabs could be activated simultaneously when using the same parameters in different routes.
|
||||||
|
- Fixed an issue where the right-click menu on a tab displayed incorrectly when passing `params` parameters.
|
||||||
|
|
||||||
|
### 🍏 Perf
|
||||||
|
|
||||||
|
- Optimized the `nprogress` progress bar. It no longer displays when reloading a page or requesting an interface, improving the user experience.
|
||||||
|
- Optimized the timing of capturing all unmatched routes and redirecting to a full-screen `404` page.
|
||||||
|
- Explicitly configured the `Tailwind CSS` entry file path to improve the contextual recognition and prompting performance of the `Tailwind CSS IntelliSense` plugin
|
||||||
|
|
||||||
# 6.1.0 (2025-07-31)
|
# 6.1.0 (2025-07-31)
|
||||||
|
|
||||||
### ✔️ Refactor
|
### ✔️ Refactor
|
||||||
|
|||||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,3 +1,23 @@
|
|||||||
|
# 6.2.0 (2025-10-16)
|
||||||
|
|
||||||
|
### 🎫 Features
|
||||||
|
|
||||||
|
- Added full-screen `403`, `404`, and `500` error pages. These full-screen error pages are clear and secure, improving the user experience.
|
||||||
|
|
||||||
|
### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Fixed an issue where the built-in homepage did not have a `name` configured, causing cache invalidation after setting the page cache.
|
||||||
|
- Fixed an issue where, in an embedded same-origin `iframe` page, when the `beforeunload` event was registered, right-clicking a tab and reloading it would cause the browser to prompt two confirmation blocks.
|
||||||
|
- Fixed an issue where pages with `keepAlive: true` set to cache invalidation when the initial load was slow.
|
||||||
|
- Fixed an issue where multiple tabs could be activated simultaneously when using the same parameters in different routes.
|
||||||
|
- Fixed an issue where the right-click menu on a tab displayed incorrectly when passing `params` parameters.
|
||||||
|
|
||||||
|
### 🍏 Perf
|
||||||
|
|
||||||
|
- Optimized the `nprogress` progress bar. It no longer displays when reloading a page or requesting an interface, improving the user experience.
|
||||||
|
- Optimized the timing of capturing all unmatched routes and redirecting to a full-screen `404` page.
|
||||||
|
- Explicitly configured the `Tailwind CSS` entry file path to improve the contextual recognition and prompting performance of the `Tailwind CSS IntelliSense` plugin
|
||||||
|
|
||||||
# 6.1.0 (2025-07-31)
|
# 6.1.0 (2025-07-31)
|
||||||
|
|
||||||
### ✔️ Refactor
|
### ✔️ Refactor
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
|
# 6.2.0 (2025-10-16)
|
||||||
|
|
||||||
|
### 🎫 Feat
|
||||||
|
|
||||||
|
- 添加全屏`403`、`404`、`500`页面,全屏错误页面清晰且安全,提升用户体验
|
||||||
|
|
||||||
|
### 🐞 Bug fixes
|
||||||
|
|
||||||
|
- 修复内置的首页未设置`name`导致设置页面缓存后缓存无效的问题
|
||||||
|
- 修复在内嵌同源`iframe`页面中,当其注册了`beforeunload`事件时,右键标签页点击重新加载导致浏览器弹出两次确认拦截的问题
|
||||||
|
- 修复设置了`keepAlive: true`的页面在初次加载缓慢的情况下出现的页面缓存失效的问题
|
||||||
|
- 修复不同路由使用相同参数时,多个标签页会同时被激活的问题
|
||||||
|
- 修复`params`传参模式下标签页右键菜单显示不正确的问题
|
||||||
|
|
||||||
|
### 🍏 Perf
|
||||||
|
|
||||||
|
- 优化`nprogress`进度条,页面重进或接口请求时不再显示进度条,提升用户体验
|
||||||
|
- 优化当捕获所有未匹配路由并跳转全屏`404`页面的时机
|
||||||
|
- 显式配置`Tailwind CSS`入口文件路径,优化`Tailwind CSS IntelliSense`插件的上下文识别与提示性能
|
||||||
|
|
||||||
# 6.1.0 (2025-07-31)
|
# 6.1.0 (2025-07-31)
|
||||||
|
|
||||||
### ✔️ Refactor
|
### ✔️ Refactor
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-pure-admin",
|
"name": "vue-pure-admin",
|
||||||
"version": "6.1.0",
|
"version": "6.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"Version": "6.1.0",
|
"Version": "6.2.0",
|
||||||
"Title": "PureAdmin",
|
"Title": "PureAdmin",
|
||||||
"FixedHeader": true,
|
"FixedHeader": true,
|
||||||
"HiddenSideBar": false,
|
"HiddenSideBar": false,
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ function onClickDrop(key, item, selectRoute?: RouteConfigs) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showMenuModel(route.fullPath, route.query);
|
showMenuModel(route.fullPath, route.query, route.params);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,15 +391,18 @@ function disabledMenus(value: boolean, fixedTag = false) {
|
|||||||
function showMenuModel(
|
function showMenuModel(
|
||||||
currentPath: string,
|
currentPath: string,
|
||||||
query: object = {},
|
query: object = {},
|
||||||
|
params: object = {},
|
||||||
refresh = false
|
refresh = false
|
||||||
) {
|
) {
|
||||||
const allRoute = multiTags.value;
|
const allRoute = multiTags.value;
|
||||||
const routeLength = multiTags.value.length;
|
const routeLength = multiTags.value.length;
|
||||||
let currentIndex = -1;
|
let currentIndex = -1;
|
||||||
if (isAllEmpty(query)) {
|
if (!isAllEmpty(params)) {
|
||||||
currentIndex = allRoute.findIndex(v => v.path === currentPath);
|
currentIndex = allRoute.findIndex(v => isEqual(v.params, params));
|
||||||
} else {
|
} else if (!isAllEmpty(query)) {
|
||||||
currentIndex = allRoute.findIndex(v => isEqual(v.query, query));
|
currentIndex = allRoute.findIndex(v => isEqual(v.query, query));
|
||||||
|
} else {
|
||||||
|
currentIndex = allRoute.findIndex(v => v.path === currentPath);
|
||||||
}
|
}
|
||||||
function fixedTagDisabled() {
|
function fixedTagDisabled() {
|
||||||
if (allRoute[currentIndex]?.meta?.fixedTag) {
|
if (allRoute[currentIndex]?.meta?.fixedTag) {
|
||||||
@@ -465,14 +468,14 @@ function openMenu(tag, e) {
|
|||||||
} else if (route.path !== tag.path && route.name !== tag.name) {
|
} else if (route.path !== tag.path && route.name !== tag.name) {
|
||||||
// 右键菜单不匹配当前路由,隐藏刷新
|
// 右键菜单不匹配当前路由,隐藏刷新
|
||||||
tagsViews[0].show = false;
|
tagsViews[0].show = false;
|
||||||
showMenuModel(tag.path, tag.query);
|
showMenuModel(tag.path, tag.query, tag.params);
|
||||||
} else if (multiTags.value.length === 2 && route.path !== tag.path) {
|
} else if (multiTags.value.length === 2 && route.path !== tag.path) {
|
||||||
showMenus(true);
|
showMenus(true);
|
||||||
// 只有两个标签时不显示关闭其他标签页
|
// 只有两个标签时不显示关闭其他标签页
|
||||||
tagsViews[4].show = false;
|
tagsViews[4].show = false;
|
||||||
} else if (route.path === tag.path) {
|
showMenuModel(tag.path, tag.query, tag.params);
|
||||||
// 右键当前激活的菜单
|
} else {
|
||||||
showMenuModel(tag.path, tag.query, true);
|
showMenuModel(tag.path, tag.query, tag.params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSelect.value = tag;
|
currentSelect.value = tag;
|
||||||
|
|||||||
@@ -114,14 +114,21 @@ export function useTags() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
function conditionHandle(item, previous, next) {
|
function conditionHandle(item, previous, next) {
|
||||||
|
const currentName = route.name || "";
|
||||||
|
const itemName = item.name || "";
|
||||||
|
|
||||||
if (isBoolean(route?.meta?.showLink) && route?.meta?.showLink === false) {
|
if (isBoolean(route?.meta?.showLink) && route?.meta?.showLink === false) {
|
||||||
if (Object.keys(route.query).length > 0) {
|
if (Object.keys(route.query).length > 0) {
|
||||||
return isEqual(route.query, item.query) ? previous : next;
|
return currentName === itemName && isEqual(route.query, item.query)
|
||||||
|
? previous
|
||||||
|
: next;
|
||||||
} else {
|
} else {
|
||||||
return isEqual(route.params, item.params) ? previous : next;
|
return currentName === itemName && isEqual(route.params, item.params)
|
||||||
|
? previous
|
||||||
|
: next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return route.path === item.path ? previous : next;
|
return currentName === itemName ? previous : next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,22 +80,15 @@ export const useMultiTagsStore = defineStore("pure-multiTags", {
|
|||||||
if (isBoolean(tagVal?.meta?.showLink) && !tagVal?.meta?.showLink)
|
if (isBoolean(tagVal?.meta?.showLink) && !tagVal?.meta?.showLink)
|
||||||
return;
|
return;
|
||||||
const tagPath = tagVal.path;
|
const tagPath = tagVal.path;
|
||||||
// 判断tag是否已存在
|
|
||||||
const tagHasExits = this.multiTags.some(tag => {
|
const tagHasExits = this.multiTags.some(tag => {
|
||||||
return tag.path === tagPath;
|
return (
|
||||||
|
tag.path === tagPath &&
|
||||||
|
isEqual(tag?.query, tagVal?.query) &&
|
||||||
|
isEqual(tag?.params, tagVal?.params)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 判断tag中的query键值是否相等
|
if (tagHasExits) return;
|
||||||
const tagQueryHasExits = this.multiTags.some(tag => {
|
|
||||||
return isEqual(tag?.query, tagVal?.query);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 判断tag中的params键值是否相等
|
|
||||||
const tagParamsHasExits = this.multiTags.some(tag => {
|
|
||||||
return isEqual(tag?.params, tagVal?.params);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (tagHasExits && tagQueryHasExits && tagParamsHasExits) return;
|
|
||||||
|
|
||||||
// 动态路由可打开的最大数量
|
// 动态路由可打开的最大数量
|
||||||
const dynamicLevel = tagVal?.meta?.dynamicLevel ?? -1;
|
const dynamicLevel = tagVal?.meta?.dynamicLevel ?? -1;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { defineStore } from "pinia";
|
|||||||
import {
|
import {
|
||||||
type cacheType,
|
type cacheType,
|
||||||
store,
|
store,
|
||||||
debounce,
|
|
||||||
ascending,
|
ascending,
|
||||||
getKeyList,
|
getKeyList,
|
||||||
filterTree,
|
filterTree,
|
||||||
@@ -33,33 +32,35 @@ export const usePermissionStore = defineStore("pure-permission", {
|
|||||||
this.constantMenus.concat(routes) as any
|
this.constantMenus.concat(routes) as any
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
/** 监听缓存页面是否存在于标签页,不存在则删除 */
|
||||||
|
clearCache() {
|
||||||
|
let cacheLength = this.cachePageList.length;
|
||||||
|
const nameList = getKeyList(useMultiTagsStoreHook().multiTags, "name");
|
||||||
|
while (cacheLength > 0) {
|
||||||
|
nameList.findIndex(v => v === this.cachePageList[cacheLength - 1]) ===
|
||||||
|
-1 &&
|
||||||
|
this.cachePageList.splice(
|
||||||
|
this.cachePageList.indexOf(this.cachePageList[cacheLength - 1]),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
cacheLength--;
|
||||||
|
}
|
||||||
|
},
|
||||||
cacheOperate({ mode, name }: cacheType) {
|
cacheOperate({ mode, name }: cacheType) {
|
||||||
const delIndex = this.cachePageList.findIndex(v => v === name);
|
const delIndex = this.cachePageList.findIndex(v => v === name);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "refresh":
|
case "refresh":
|
||||||
this.cachePageList = this.cachePageList.filter(v => v !== name);
|
this.cachePageList = this.cachePageList.filter(v => v !== name);
|
||||||
|
this.clearCache();
|
||||||
break;
|
break;
|
||||||
case "add":
|
case "add":
|
||||||
this.cachePageList.push(name);
|
this.cachePageList.push(name);
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
delIndex !== -1 && this.cachePageList.splice(delIndex, 1);
|
delIndex !== -1 && this.cachePageList.splice(delIndex, 1);
|
||||||
|
this.clearCache();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/** 监听缓存页面是否存在于标签页,不存在则删除 */
|
|
||||||
debounce(() => {
|
|
||||||
let cacheLength = this.cachePageList.length;
|
|
||||||
const nameList = getKeyList(useMultiTagsStoreHook().multiTags, "name");
|
|
||||||
while (cacheLength > 0) {
|
|
||||||
nameList.findIndex(v => v === this.cachePageList[cacheLength - 1]) ===
|
|
||||||
-1 &&
|
|
||||||
this.cachePageList.splice(
|
|
||||||
this.cachePageList.indexOf(this.cachePageList[cacheLength - 1]),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
cacheLength--;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
},
|
},
|
||||||
/** 清空缓存页面 */
|
/** 清空缓存页面 */
|
||||||
clearAllCachePage() {
|
clearAllCachePage() {
|
||||||
|
|||||||
Reference in New Issue
Block a user