mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-05-21 11:59:20 +08:00
bug fixed: 修复浏览器标题渲染错误问题,以及v4.0.2的一些小细节更新
This commit is contained in:
parent
f21eeddd7f
commit
dbb27902aa
@ -74,12 +74,22 @@ module.exports = {
|
|||||||
'no-ex-assign': 2, // 禁止给 `catch` 语句中的异常参数赋值
|
'no-ex-assign': 2, // 禁止给 `catch` 语句中的异常参数赋值
|
||||||
'no-extend-native': 2, // 禁止扩展 `native` 对象
|
'no-extend-native': 2, // 禁止扩展 `native` 对象
|
||||||
'no-extra-bind': 2, // 禁止不必要的函数绑定
|
'no-extra-bind': 2, // 禁止不必要的函数绑定
|
||||||
'no-extra-boolean-cast': 2, // 禁止不必要的 `bool` 转换
|
'no-extra-boolean-cast': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
enforceForLogicalOperands: true,
|
||||||
|
},
|
||||||
|
], // 禁止不必要的 `bool` 转换
|
||||||
'no-extra-parens': 0, // 禁止非必要的括号
|
'no-extra-parens': 0, // 禁止非必要的括号
|
||||||
semi: ['error', 'never', { beforeStatementContinuationChars: 'always' }],
|
semi: ['error', 'never', { beforeStatementContinuationChars: 'always' }],
|
||||||
'no-fallthrough': 1, // 禁止 `switch` 穿透
|
'no-fallthrough': 1, // 禁止 `switch` 穿透
|
||||||
'no-func-assign': 2, // 禁止重复的函数声明
|
'no-func-assign': 2, // 禁止重复的函数声明
|
||||||
'no-implicit-coercion': 1, // 禁止隐式转换
|
'no-implicit-coercion': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
allow: ['!!', '~'],
|
||||||
|
},
|
||||||
|
], // 禁止隐式转换
|
||||||
'no-implied-eval': 2, // 禁止使用隐式 `eval`
|
'no-implied-eval': 2, // 禁止使用隐式 `eval`
|
||||||
'no-invalid-regexp': 2, // 禁止无效的正则表达式
|
'no-invalid-regexp': 2, // 禁止无效的正则表达式
|
||||||
'no-invalid-this': 2, // 禁止无效的 `this`
|
'no-invalid-this': 2, // 禁止无效的 `this`
|
||||||
|
@ -6,6 +6,13 @@
|
|||||||
|
|
||||||
- 新增平级路由配置(router meta)配置项,sameLevel 允许你将子路由标记为平级模式,跳转时不会出发菜单、标签页更新,仅会更新面包屑
|
- 新增平级路由配置(router meta)配置项,sameLevel 允许你将子路由标记为平级模式,跳转时不会出发菜单、标签页更新,仅会更新面包屑
|
||||||
- 修改路由菜单显示、隐藏逻辑,现在仅会针对权限的验证匹配选择是否加入菜单列表中
|
- 修改路由菜单显示、隐藏逻辑,现在仅会针对权限的验证匹配选择是否加入菜单列表中
|
||||||
|
- 更新 setupAppMenu 方法触发时机(Layout => menu store),现在将在 pinia menu store 初始化时触发 App Menu 更新
|
||||||
|
- 更新了 utils 包中的一些方法,进行了一些重写和重命名
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- 修复不能正确渲染浏览器标题问题
|
||||||
|
- 修复初始化模板菜单函数与菜单更新函数重复执行一些方法的问题
|
||||||
|
|
||||||
## 4.0.1
|
## 4.0.1
|
||||||
|
|
||||||
|
12
src/App.tsx
12
src/App.tsx
@ -3,7 +3,7 @@ import { RouterView } from 'vue-router'
|
|||||||
import GlobalSpin from '@/spin/index'
|
import GlobalSpin from '@/spin/index'
|
||||||
import LockScreen from '@/components/AppComponents/AppLockScreen/index'
|
import LockScreen from '@/components/AppComponents/AppLockScreen/index'
|
||||||
|
|
||||||
import { getCache } from '@/utils/cache'
|
import { getStorage } from '@/utils/cache'
|
||||||
import { get } from 'lodash-es'
|
import { get } from 'lodash-es'
|
||||||
import { useSetting } from '@/store'
|
import { useSetting } from '@/store'
|
||||||
import { addClass, removeClass, addStyle, colorToRgba } from '@/utils/element'
|
import { addClass, removeClass, addStyle, colorToRgba } from '@/utils/element'
|
||||||
@ -24,18 +24,20 @@ const App = defineComponent({
|
|||||||
} = __APP_CFG__ // 默认主题色
|
} = __APP_CFG__ // 默认主题色
|
||||||
const body = document.body
|
const body = document.body
|
||||||
|
|
||||||
const primaryColorOverride = getCache<SettingState>(
|
const primaryColorOverride = getStorage<SettingState>(
|
||||||
'piniaSettingStore',
|
'piniaSettingStore',
|
||||||
'localStorage',
|
'localStorage',
|
||||||
|
primaryColor,
|
||||||
)
|
)
|
||||||
const _p = get(
|
const _p = get(
|
||||||
primaryColorOverride,
|
primaryColorOverride as SettingState,
|
||||||
'primaryColorOverride.common.primaryColor',
|
'primaryColorOverride.common.primaryColor',
|
||||||
|
primaryColor,
|
||||||
)
|
)
|
||||||
const _fp = colorToRgba(_p || primaryColor, 0.3)
|
const _fp = colorToRgba(_p, 0.3)
|
||||||
|
|
||||||
/** 设置全局主题色 css 变量 */
|
/** 设置全局主题色 css 变量 */
|
||||||
body.style.setProperty('--ray-theme-primary-color', _p || primaryColor)
|
body.style.setProperty('--ray-theme-primary-color', _p)
|
||||||
body.style.setProperty(
|
body.style.setProperty(
|
||||||
'--ray-theme-primary-fade-color',
|
'--ray-theme-primary-fade-color',
|
||||||
_fp || primaryFadeColor,
|
_fp || primaryFadeColor,
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
import { useAxiosInterceptor, axiosCanceler } from '@/axios/helper/interceptor'
|
import { useAxiosInterceptor, axiosCanceler } from '@/axios/helper/interceptor'
|
||||||
import { appendRequestHeaders } from '@/axios/helper/axiosCopilot'
|
import { appendRequestHeaders } from '@/axios/helper/axiosCopilot'
|
||||||
import { APP_CATCH_KEY } from '@/appConfig/appConfig'
|
import { APP_CATCH_KEY } from '@/appConfig/appConfig'
|
||||||
import { getCache } from '@/utils/cache'
|
import { getStorage } from '@/utils/cache'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
RequestInterceptorConfig,
|
RequestInterceptorConfig,
|
||||||
@ -40,7 +40,7 @@ const { setImplement } = useAxiosInterceptor()
|
|||||||
* 当然你也可以根据 request instance 来特殊处理, 这里暂时不做演示
|
* 当然你也可以根据 request instance 来特殊处理, 这里暂时不做演示
|
||||||
*/
|
*/
|
||||||
const requestHeaderToken = (ins: RequestInterceptorConfig, mode: string) => {
|
const requestHeaderToken = (ins: RequestInterceptorConfig, mode: string) => {
|
||||||
const token = getCache<string>(APP_CATCH_KEY.token)
|
const token = getStorage<string>(APP_CATCH_KEY.token)
|
||||||
|
|
||||||
if (ins.url) {
|
if (ins.url) {
|
||||||
// TODO: 根据 url 不同是否设置 token
|
// TODO: 根据 url 不同是否设置 token
|
||||||
|
@ -23,7 +23,7 @@ import { NAvatar, NSpace } from 'naive-ui'
|
|||||||
|
|
||||||
import { avatarProps, spaceProps } from 'naive-ui'
|
import { avatarProps, spaceProps } from 'naive-ui'
|
||||||
import { APP_CATCH_KEY } from '@/appConfig/appConfig'
|
import { APP_CATCH_KEY } from '@/appConfig/appConfig'
|
||||||
import { getCache } from '@/utils/cache'
|
import { getStorage } from '@/utils/cache'
|
||||||
|
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import type { AvatarProps, SpaceProps } from 'naive-ui'
|
import type { AvatarProps, SpaceProps } from 'naive-ui'
|
||||||
@ -48,7 +48,7 @@ const AppAvatar = defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const signin = getCache<SigninCallback>(APP_CATCH_KEY.signin)
|
const signin = getStorage<SigninCallback>(APP_CATCH_KEY.signin)
|
||||||
const cssVars = computed(() => {
|
const cssVars = computed(() => {
|
||||||
const vars = {
|
const vars = {
|
||||||
'--app-avatar-cursor': props.cursor,
|
'--app-avatar-cursor': props.cursor,
|
||||||
|
@ -9,6 +9,7 @@ import { useVueRouter } from '@/router/helper/useVueRouter'
|
|||||||
|
|
||||||
import type { MenuInst } from 'naive-ui'
|
import type { MenuInst } from 'naive-ui'
|
||||||
import type { NaiveMenuOptions } from '@/types/modules/component'
|
import type { NaiveMenuOptions } from '@/types/modules/component'
|
||||||
|
import type { AppMenuOption } from '@/types/modules/app'
|
||||||
|
|
||||||
const LayoutMenu = defineComponent({
|
const LayoutMenu = defineComponent({
|
||||||
name: 'LayoutMenu',
|
name: 'LayoutMenu',
|
||||||
@ -106,7 +107,9 @@ const LayoutMenu = defineComponent({
|
|||||||
collapsed={this.modelCollapsed}
|
collapsed={this.modelCollapsed}
|
||||||
collapsedIconSize={APP_MENU_CONFIG.MENU_COLLAPSED_ICON_SIZE}
|
collapsedIconSize={APP_MENU_CONFIG.MENU_COLLAPSED_ICON_SIZE}
|
||||||
collapsedWidth={APP_MENU_CONFIG.MENU_COLLAPSED_WIDTH}
|
collapsedWidth={APP_MENU_CONFIG.MENU_COLLAPSED_WIDTH}
|
||||||
onUpdateValue={this.changeMenuModelValue.bind(this)}
|
onUpdateValue={(key, op) => {
|
||||||
|
this.changeMenuModelValue(key, op as unknown as AppMenuOption)
|
||||||
|
}}
|
||||||
accordion={APP_MENU_CONFIG.MENU_ACCORDION}
|
accordion={APP_MENU_CONFIG.MENU_ACCORDION}
|
||||||
/>
|
/>
|
||||||
</NLayoutSider>
|
</NLayoutSider>
|
||||||
|
@ -33,10 +33,10 @@ import { uuid } from '@/utils/hook'
|
|||||||
import { hasClass } from '@/utils/element'
|
import { hasClass } from '@/utils/element'
|
||||||
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
||||||
import { ROOT_ROUTE } from '@/appConfig/appConfig'
|
import { ROOT_ROUTE } from '@/appConfig/appConfig'
|
||||||
import { getElement } from '@use-utils/element'
|
import { getElements } from '@use-utils/element'
|
||||||
|
|
||||||
import type { MenuOption, ScrollbarInst } from 'naive-ui'
|
import type { MenuOption, ScrollbarInst } from 'naive-ui'
|
||||||
import type { MenuTagOptions } from '@/types/modules/app'
|
import type { MenuTagOptions, AppMenuOption } from '@/types/modules/app'
|
||||||
|
|
||||||
const MenuTag = defineComponent({
|
const MenuTag = defineComponent({
|
||||||
name: 'MenuTag',
|
name: 'MenuTag',
|
||||||
@ -247,7 +247,7 @@ const MenuTag = defineComponent({
|
|||||||
*
|
*
|
||||||
* @param item 当前菜单值
|
* @param item 当前菜单值
|
||||||
*/
|
*/
|
||||||
const handleTagClick = (item: MenuOption) => {
|
const handleTagClick = (item: AppMenuOption) => {
|
||||||
changeMenuModelValue(item.key as string, item)
|
changeMenuModelValue(item.key as string, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ const MenuTag = defineComponent({
|
|||||||
/** 动态更新 menu tag 所在位置 */
|
/** 动态更新 menu tag 所在位置 */
|
||||||
const positionMenuTag = () => {
|
const positionMenuTag = () => {
|
||||||
nextTick().then(() => {
|
nextTick().then(() => {
|
||||||
const tags = getElement<HTMLElement>(
|
const tags = getElements<HTMLElement>(
|
||||||
`attr:${MENU_TAG_DATA}="${menuKey.value}"`,
|
`attr:${MENU_TAG_DATA}="${menuKey.value}"`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,12 +42,16 @@ const Breadcrumb = defineComponent({
|
|||||||
key: string | number,
|
key: string | number,
|
||||||
option: DropdownOption,
|
option: DropdownOption,
|
||||||
) => {
|
) => {
|
||||||
changeMenuModelValue(key, option)
|
changeMenuModelValue(key, option as unknown as AppMenuOption)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBreadcrumbItemClick = (option: AppMenuOption) => {
|
const handleBreadcrumbItemClick = (option: AppMenuOption) => {
|
||||||
if (!option.children?.length) {
|
if (!option.children?.length) {
|
||||||
changeMenuModelValue(option.key, option as unknown as MenuOption)
|
const { meta = {} } = option
|
||||||
|
|
||||||
|
if (!meta.sameLevel) {
|
||||||
|
changeMenuModelValue(option.key, option)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ const GlobalSeach = defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSearchItemClick = (option: MenuOption) => {
|
const handleSearchItemClick = (option: AppMenuOption) => {
|
||||||
const meta = option.meta as AppRouteMeta
|
const meta = option.meta as AppRouteMeta
|
||||||
|
|
||||||
/** 如果配置站外跳转则不会关闭搜索框 */
|
/** 如果配置站外跳转则不会关闭搜索框 */
|
||||||
@ -118,7 +118,7 @@ const GlobalSeach = defineComponent({
|
|||||||
} else {
|
} else {
|
||||||
modelShow.value = false
|
modelShow.value = false
|
||||||
|
|
||||||
changeMenuModelValue(option.key as string, option)
|
changeMenuModelValue(option.key, option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import { set } from 'lodash-es'
|
import { set } from 'lodash-es'
|
||||||
import { zhCN, dateZhCN } from 'naive-ui' // 导入 `naive ui` 中文包
|
import { zhCN, dateZhCN } from 'naive-ui' // 导入 `naive ui` 中文包
|
||||||
import { getCache } from '@use-utils/cache'
|
import { getStorage } from '@use-utils/cache'
|
||||||
import { SYSTEM_DEFAULT_LOCAL } from '@/appConfig/localConfig'
|
import { SYSTEM_DEFAULT_LOCAL } from '@/appConfig/localConfig'
|
||||||
import { APP_CATCH_KEY } from '@/appConfig/appConfig'
|
import { APP_CATCH_KEY } from '@/appConfig/appConfig'
|
||||||
|
|
||||||
@ -126,10 +126,11 @@ export const naiveLocales = (key: string) => {
|
|||||||
* @remak 未避免出现加载语言错误问题, 故而在 `main.ts` 注册时, 应优先加载 `i18n` 避免出现该问题
|
* @remak 未避免出现加载语言错误问题, 故而在 `main.ts` 注册时, 应优先加载 `i18n` 避免出现该问题
|
||||||
*/
|
*/
|
||||||
export const getAppDefaultLanguage = () => {
|
export const getAppDefaultLanguage = () => {
|
||||||
const language = getCache<string>(
|
const language = getStorage<string>(
|
||||||
APP_CATCH_KEY.localeLanguage,
|
APP_CATCH_KEY.localeLanguage,
|
||||||
'localStorage',
|
'localStorage',
|
||||||
|
SYSTEM_DEFAULT_LOCAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
return language ? language : SYSTEM_DEFAULT_LOCAL
|
return language || SYSTEM_DEFAULT_LOCAL
|
||||||
}
|
}
|
||||||
|
@ -115,5 +115,5 @@ hidden: 是否显示
|
|||||||
noLocalTitle: 不使用国际化渲染 Menu Titile
|
noLocalTitle: 不使用国际化渲染 Menu Titile
|
||||||
ignoreAutoResetScroll: 该页面内容区域自动初始化滚动条位置
|
ignoreAutoResetScroll: 该页面内容区域自动初始化滚动条位置
|
||||||
keepAlive: 是否缓存该页面(需要配置 APP_KEEP_ALIVE setupKeepAlive 属性为 true 启用才有效)
|
keepAlive: 是否缓存该页面(需要配置 APP_KEEP_ALIVE setupKeepAlive 属性为 true 启用才有效)
|
||||||
sameLevel: 是否标记该路由为平级模式
|
sameLevel: 是否标记该路由为平级模式,如果标记为平级模式,会使路由菜单项隐藏。如果在含有子节点处,设置了该属性,会导致子节点全部被隐藏
|
||||||
```
|
```
|
||||||
|
@ -20,11 +20,10 @@
|
|||||||
* 当然, 你可以指定一个超级管理员角色, 默认获取全部路由
|
* 当然, 你可以指定一个超级管理员角色, 默认获取全部路由
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getCache, setCache } from '@/utils/cache'
|
import { getStorage } from '@/utils/cache'
|
||||||
import { useSignin } from '@/store'
|
|
||||||
import { APP_CATCH_KEY, ROOT_ROUTE } from '@/appConfig/appConfig'
|
import { APP_CATCH_KEY, ROOT_ROUTE } from '@/appConfig/appConfig'
|
||||||
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
import { redirectRouterToDashboard } from '@/router/helper/routerCopilot'
|
||||||
import { validRole, validMenuItemShow } from '@/router/helper/routerCopilot'
|
import { validRole } from '@/router/helper/routerCopilot'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
Router,
|
Router,
|
||||||
@ -38,8 +37,12 @@ export const permissionRouter = (router: Router) => {
|
|||||||
const { beforeEach } = router
|
const { beforeEach } = router
|
||||||
|
|
||||||
beforeEach((to, from, next) => {
|
beforeEach((to, from, next) => {
|
||||||
const token = getCache<string>(APP_CATCH_KEY.token)
|
const token = getStorage<string>(APP_CATCH_KEY.token)
|
||||||
const route = getCache<string>('menuKey') || ROOT_ROUTE.path
|
const route = getStorage<string>(
|
||||||
|
'menuKey',
|
||||||
|
'sessionStorage',
|
||||||
|
ROOT_ROUTE.path,
|
||||||
|
) as string
|
||||||
const { meta } = to
|
const { meta } = to
|
||||||
|
|
||||||
if (token !== null) {
|
if (token !== null) {
|
||||||
|
@ -20,7 +20,7 @@ import {
|
|||||||
import { useSignin } from '@/store'
|
import { useSignin } from '@/store'
|
||||||
import { useVueRouter } from '@/router/helper/useVueRouter'
|
import { useVueRouter } from '@/router/helper/useVueRouter'
|
||||||
import { ROOT_ROUTE } from '@/appConfig/appConfig'
|
import { ROOT_ROUTE } from '@/appConfig/appConfig'
|
||||||
import { setCache } from '@/utils/cache'
|
import { setStorage } from '@/utils/cache'
|
||||||
|
|
||||||
import type { Router } from 'vue-router'
|
import type { Router } from 'vue-router'
|
||||||
import type { AppRouteMeta } from '@/router/type'
|
import type { AppRouteMeta } from '@/router/type'
|
||||||
@ -58,18 +58,27 @@ export const validRole = (meta: AppRouteMeta) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @remark 校验当前路由
|
* @remark 校验当前路由是否显示
|
||||||
*
|
*
|
||||||
* 该方法进行校验时, 会将 hidden 与 role 一起进行校验
|
* 该方法进行校验时, 会将 hidden 与 sameLevel 一起进行校验
|
||||||
* 如果有一条不满足校验, 则视为校验失败
|
* sameLevel 的优先级最高
|
||||||
*
|
*
|
||||||
* 如果你仅仅是希望校验是否满足权限, 应该使用另一个方法 validRole
|
* 如果你仅仅是希望校验是否满足权限, 应该使用另一个方法 validRole
|
||||||
*/
|
*/
|
||||||
export const validMenuItemShow = (option: AppMenuOption) => {
|
export const validMenuItemShow = (option: AppMenuOption) => {
|
||||||
const { meta = {} } = option
|
const { meta = {} } = option
|
||||||
const { hidden } = meta
|
const { hidden, sameLevel } = meta
|
||||||
|
|
||||||
return hidden === undefined || hidden === false ? true : false
|
// 如果该路由被标记为平级模式, 则会强制不显示在菜单中
|
||||||
|
if (sameLevel) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sameLevel && !hidden) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !hidden ? true : false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +128,7 @@ export const redirectRouterToDashboard = (isReplace = true) => {
|
|||||||
const { push, replace } = router
|
const { push, replace } = router
|
||||||
const { path } = ROOT_ROUTE
|
const { path } = ROOT_ROUTE
|
||||||
|
|
||||||
setCache('menuKey', path)
|
setStorage('menuKey', path)
|
||||||
|
|
||||||
isReplace ? push(path) : replace(path)
|
isReplace ? push(path) : replace(path)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
import { LAYOUT } from '@/router/constant/index'
|
|
||||||
|
|
||||||
const multiMenu: AppRouteRecordRaw = {
|
const multiMenu: AppRouteRecordRaw = {
|
||||||
path: '/multi',
|
path: '/multi',
|
||||||
name: 'MultiMenu',
|
name: 'MultiMenu',
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
import { LAYOUT } from '@/router/constant/index'
|
|
||||||
|
|
||||||
const rely: AppRouteRecordRaw = {
|
const rely: AppRouteRecordRaw = {
|
||||||
path: '/rely',
|
path: '/rely',
|
||||||
name: 'RelyAbout',
|
name: 'RelyAbout',
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from '@/locales/useI18n'
|
import { t } from '@/locales/useI18n'
|
||||||
|
import { LAYOUT } from '@/router/constant/index'
|
||||||
|
|
||||||
import type { AppRouteRecordRaw } from '@/router/type'
|
import type { AppRouteRecordRaw } from '@/router/type'
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
import { APP_MENU_CONFIG, ROOT_ROUTE } from '@/appConfig/appConfig'
|
import { APP_MENU_CONFIG, ROOT_ROUTE } from '@/appConfig/appConfig'
|
||||||
import RayIcon from '@/components/RayIcon/index'
|
import RayIcon from '@/components/RayIcon/index'
|
||||||
import { isValueType } from '@/utils/hook'
|
import { isValueType } from '@/utils/hook'
|
||||||
import { getCache, setCache } from '@/utils/cache'
|
import { getStorage, setStorage } from '@/utils/cache'
|
||||||
|
|
||||||
import type { VNode } from 'vue'
|
import type { VNode } from 'vue'
|
||||||
import type {
|
import type {
|
||||||
@ -174,10 +174,11 @@ export const hasMenuIcon = (option: AppMenuOption) => {
|
|||||||
/** 获取缓存的 menu key, 如果未获取到则使用 ROOTROUTE path 当作默认激活路由菜单 */
|
/** 获取缓存的 menu key, 如果未获取到则使用 ROOTROUTE path 当作默认激活路由菜单 */
|
||||||
export const getCatchMenuKey = () => {
|
export const getCatchMenuKey = () => {
|
||||||
const { path: rootPath } = ROOT_ROUTE
|
const { path: rootPath } = ROOT_ROUTE
|
||||||
const cacheMenuKey =
|
const cacheMenuKey = getStorage<AppMenuKey>(
|
||||||
getCache<AppMenuKey>('menuKey') === null
|
'menuKey',
|
||||||
? rootPath
|
'sessionStorage',
|
||||||
: getCache<AppMenuKey>('menuKey')
|
rootPath,
|
||||||
|
)
|
||||||
|
|
||||||
return cacheMenuKey
|
return cacheMenuKey
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
import { NEllipsis } from 'naive-ui'
|
import { NEllipsis } from 'naive-ui'
|
||||||
|
|
||||||
import { getCache, setCache } from '@/utils/cache'
|
import { setStorage } from '@/utils/cache'
|
||||||
import { validMenuItemShow, validRole } from '@/router/helper/routerCopilot'
|
import { validRole, validMenuItemShow } from '@/router/helper/routerCopilot'
|
||||||
import {
|
import {
|
||||||
parseAndFindMatchingNodes,
|
parseAndFindMatchingNodes,
|
||||||
updateDocumentTitle,
|
updateDocumentTitle,
|
||||||
@ -86,7 +86,10 @@ export const useMenu = defineStore(
|
|||||||
*
|
*
|
||||||
* 如果识别到为平级模式, 则会自动追加一层面包屑
|
* 如果识别到为平级模式, 则会自动追加一层面包屑
|
||||||
*/
|
*/
|
||||||
const setBreadcrumbOptions = (key: string | number, option: MenuOption) => {
|
const setBreadcrumbOptions = (
|
||||||
|
key: string | number,
|
||||||
|
option: AppMenuOption,
|
||||||
|
) => {
|
||||||
const { meta } = option as unknown as AppRouteRecordRaw
|
const { meta } = option as unknown as AppRouteRecordRaw
|
||||||
|
|
||||||
menuState.breadcrumbOptions = getCompleteRoutePath(menuState.options, key)
|
menuState.breadcrumbOptions = getCompleteRoutePath(menuState.options, key)
|
||||||
@ -124,12 +127,12 @@ export const useMenu = defineStore(
|
|||||||
/** 当 url 地址发生变化触发 menuTagOptions 更新 */
|
/** 当 url 地址发生变化触发 menuTagOptions 更新 */
|
||||||
const setMenuTagOptionsWhenMenuValueChange = (
|
const setMenuTagOptionsWhenMenuValueChange = (
|
||||||
key: string | number,
|
key: string | number,
|
||||||
option: MenuOption,
|
option: AppMenuOption,
|
||||||
) => {
|
) => {
|
||||||
const tag = menuState.menuTagOptions.find((curr) => curr.path === key)
|
const tag = menuState.menuTagOptions.find((curr) => curr.path === key)
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
menuState.menuTagOptions.push(option as unknown as MenuTagOptions)
|
menuState.menuTagOptions.push(option as MenuTagOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +144,11 @@ export const useMenu = defineStore(
|
|||||||
* @remark 修改 `menu key` 后的回调函数
|
* @remark 修改 `menu key` 后的回调函数
|
||||||
* @remark 修改后, 缓存当前选择 key 并且存储标签页与跳转页面(router push 操作)
|
* @remark 修改后, 缓存当前选择 key 并且存储标签页与跳转页面(router push 操作)
|
||||||
*/
|
*/
|
||||||
const changeMenuModelValue = (key: string | number, option: MenuOption) => {
|
const changeMenuModelValue = (
|
||||||
const { meta, path } = option as unknown as AppRouteRecordRaw
|
key: string | number,
|
||||||
|
option: AppMenuOption,
|
||||||
|
) => {
|
||||||
|
const { meta, path } = option
|
||||||
|
|
||||||
if (meta.windowOpen) {
|
if (meta.windowOpen) {
|
||||||
window.open(meta.windowOpen)
|
window.open(meta.windowOpen)
|
||||||
@ -169,10 +175,10 @@ export const useMenu = defineStore(
|
|||||||
/** 检查是否为根路由 */
|
/** 检查是否为根路由 */
|
||||||
const count = (path.match(new RegExp('/', 'g')) || []).length
|
const count = (path.match(new RegExp('/', 'g')) || []).length
|
||||||
|
|
||||||
/** 更新浏览器标题 */
|
|
||||||
updateDocumentTitle(option as unknown as AppMenuOption)
|
|
||||||
/** 更新缓存队列 */
|
/** 更新缓存队列 */
|
||||||
setKeepAliveInclude(option as unknown as AppMenuOption)
|
setKeepAliveInclude(option as unknown as AppMenuOption)
|
||||||
|
/** 更新浏览器标题 */
|
||||||
|
updateDocumentTitle(option as unknown as AppMenuOption)
|
||||||
|
|
||||||
if (!meta.sameLevel || (meta.sameLevel && count === 1)) {
|
if (!meta.sameLevel || (meta.sameLevel && count === 1)) {
|
||||||
/** 更新标签菜单 */
|
/** 更新标签菜单 */
|
||||||
@ -182,7 +188,7 @@ export const useMenu = defineStore(
|
|||||||
|
|
||||||
menuState.menuKey = key
|
menuState.menuKey = key
|
||||||
/** 缓存菜单 key(sessionStorage) */
|
/** 缓存菜单 key(sessionStorage) */
|
||||||
setCache('menuKey', key)
|
setStorage('menuKey', key)
|
||||||
} else {
|
} else {
|
||||||
setBreadcrumbOptions(menuState.menuKey || '', option)
|
setBreadcrumbOptions(menuState.menuKey || '', option)
|
||||||
}
|
}
|
||||||
@ -196,21 +202,33 @@ export const useMenu = defineStore(
|
|||||||
* @remark 监听路由地址变化更新菜单状态
|
* @remark 监听路由地址变化更新菜单状态
|
||||||
* @remark 递归查找匹配项
|
* @remark 递归查找匹配项
|
||||||
*/
|
*/
|
||||||
const updateMenuKeyWhenRouteUpdate = (path: string) => {
|
const updateMenuKeyWhenRouteUpdate = async (path: string) => {
|
||||||
const appRawRoutes = expandRoutes(getAppRawRoutes())
|
// 获取 `/` 出现次数(如果为 1 则表示该路径为根路由路径)
|
||||||
const count = (path.match(new RegExp('/', 'g')) || []).length
|
const count = (path.match(new RegExp('/', 'g')) || []).length
|
||||||
const fd = appRawRoutes.find((curr) => curr.path === path)
|
|
||||||
let combinePath = path
|
let combinePath = path
|
||||||
|
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
|
// 如果不是跟路径则取出最后一项字符
|
||||||
const splitPath = path.split('/').filter((curr) => curr)
|
const splitPath = path.split('/').filter((curr) => curr)
|
||||||
|
|
||||||
combinePath = splitPath[splitPath.length - 1]
|
combinePath = splitPath[splitPath.length - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd) {
|
const findMenuOption = (pathKey: string, options: AppMenuOption[]) => {
|
||||||
changeMenuModelValue(combinePath, fd as unknown as MenuOption)
|
for (const curr of options) {
|
||||||
|
if (curr.children?.length) {
|
||||||
|
findMenuOption(pathKey, curr.children)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pathKey === curr.key) {
|
||||||
|
changeMenuModelValue(pathKey, curr)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findMenuOption(combinePath, menuState.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -237,8 +255,6 @@ export const useMenu = defineStore(
|
|||||||
}),
|
}),
|
||||||
breadcrumbLabel: label.value,
|
breadcrumbLabel: label.value,
|
||||||
/** 检查该菜单项是否展示 */
|
/** 检查该菜单项是否展示 */
|
||||||
show:
|
|
||||||
meta.hidden === false || meta.hidden === undefined ? true : false,
|
|
||||||
} as AppMenuOption
|
} as AppMenuOption
|
||||||
/** 合并 icon */
|
/** 合并 icon */
|
||||||
const attr: AppMenuOption = Object.assign({}, route, {
|
const attr: AppMenuOption = Object.assign({}, route, {
|
||||||
@ -246,14 +262,12 @@ export const useMenu = defineStore(
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (option.path === getCatchMenuKey()) {
|
if (option.path === getCatchMenuKey()) {
|
||||||
/** 设置浏览器标题 */
|
/** 设置标签页(初始化时执行设置一次, 避免含有平级路由模式情况时出现不能正确设置标签页的情况) */
|
||||||
updateDocumentTitle(attr)
|
setMenuTagOptionsWhenMenuValueChange(option.path, attr)
|
||||||
setMenuTagOptionsWhenMenuValueChange(
|
|
||||||
option.path,
|
|
||||||
attr as unknown as MenuOption,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr.show = validMenuItemShow(attr)
|
||||||
|
|
||||||
return attr
|
return attr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,10 +334,10 @@ export const useMenu = defineStore(
|
|||||||
const setupPiniaMenuStore = async () => {
|
const setupPiniaMenuStore = async () => {
|
||||||
if (isSetupAppMenuLock.value) {
|
if (isSetupAppMenuLock.value) {
|
||||||
await setupAppMenu()
|
await setupAppMenu()
|
||||||
|
}
|
||||||
|
|
||||||
isSetupAppMenuLock.value = false
|
isSetupAppMenuLock.value = false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** 监听路由变化并且更新路由菜单与菜单标签 */
|
/** 监听路由变化并且更新路由菜单与菜单标签 */
|
||||||
watch(
|
watch(
|
||||||
@ -333,7 +347,7 @@ export const useMenu = defineStore(
|
|||||||
const match = newData.match(reg)?.[1]
|
const match = newData.match(reg)?.[1]
|
||||||
|
|
||||||
await setupPiniaMenuStore()
|
await setupPiniaMenuStore()
|
||||||
updateMenuKeyWhenRouteUpdate(match || '')
|
await updateMenuKeyWhenRouteUpdate(match || '')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { getAppDefaultLanguage } from '@/locales/helper'
|
import { getAppDefaultLanguage } from '@/locales/helper'
|
||||||
import { setCache } from '@use-utils/cache'
|
import { setStorage } from '@use-utils/cache'
|
||||||
import { set } from 'lodash-es'
|
import { set } from 'lodash-es'
|
||||||
import { addClass, removeClass, colorToRgba } from '@/utils/element'
|
import { addClass, removeClass, colorToRgba } from '@/utils/element'
|
||||||
import { useI18n } from '@/locales/useI18n'
|
import { useI18n } from '@/locales/useI18n'
|
||||||
@ -46,7 +46,7 @@ export const useSetting = defineStore(
|
|||||||
|
|
||||||
settingState.localeLanguage = key
|
settingState.localeLanguage = key
|
||||||
|
|
||||||
setCache('localeLanguage', key, 'localStorage')
|
setStorage('localeLanguage', key, 'localStorage')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换主题色 */
|
/** 切换主题色 */
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { isEmpty } from 'lodash-es'
|
import { isEmpty } from 'lodash-es'
|
||||||
import { removeCache } from '@/utils/cache'
|
import { removeStorage } from '@/utils/cache'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
SigninForm,
|
SigninForm,
|
||||||
@ -79,7 +79,7 @@ export const useSignin = defineStore(
|
|||||||
*/
|
*/
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
window.$message.info('账号退出中...')
|
window.$message.info('账号退出中...')
|
||||||
removeCache('all-sessionStorage')
|
removeStorage('all-sessionStorage')
|
||||||
|
|
||||||
setTimeout(() => window.location.reload())
|
setTimeout(() => window.location.reload())
|
||||||
}
|
}
|
||||||
|
@ -42,3 +42,9 @@ export type CipherParams = CryptoJS.lib.CipherParams
|
|||||||
export type AnyFunc = (...args: any[]) => any
|
export type AnyFunc = (...args: any[]) => any
|
||||||
|
|
||||||
export type AnyVoidFunc = (...args: any[]) => void
|
export type AnyVoidFunc = (...args: any[]) => void
|
||||||
|
|
||||||
|
export type PartialCSSStyleDeclaration = Partial<
|
||||||
|
Record<keyof CSSStyleDeclaration, string>
|
||||||
|
>
|
||||||
|
|
||||||
|
export type ElementSelector = string | `attr:${string}`
|
||||||
|
@ -18,16 +18,26 @@ import type { CacheType } from '@/types/modules/utils'
|
|||||||
* @param key 需要设置的key
|
* @param key 需要设置的key
|
||||||
* @param value 需要缓存的值
|
* @param value 需要缓存的值
|
||||||
*/
|
*/
|
||||||
export const setCache = <T = unknown>(
|
export const setStorage = <T = unknown>(
|
||||||
key: string,
|
key: string,
|
||||||
value: T,
|
value: T,
|
||||||
type: CacheType = 'sessionStorage',
|
type: CacheType = 'sessionStorage',
|
||||||
) => {
|
) => {
|
||||||
|
if (!key) {
|
||||||
|
console.error('Failed to set stored data: key is empty or undefined')
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const waitCacheValue = JSON.stringify(value)
|
const waitCacheValue = JSON.stringify(value)
|
||||||
|
|
||||||
type === 'localStorage'
|
type === 'localStorage'
|
||||||
? window.localStorage.setItem(key, waitCacheValue)
|
? window.localStorage.setItem(key, waitCacheValue)
|
||||||
: window.sessionStorage.setItem(key, waitCacheValue)
|
: window.sessionStorage.setItem(key, waitCacheValue)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to set stored data for key '${key}'`, error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,16 +45,27 @@ export const setCache = <T = unknown>(
|
|||||||
* @param key 需要获取目标缓存的key
|
* @param key 需要获取目标缓存的key
|
||||||
* @returns 获取缓存值
|
* @returns 获取缓存值
|
||||||
*/
|
*/
|
||||||
export const getCache = <T>(
|
export const getStorage = <T>(
|
||||||
key: string,
|
key: string,
|
||||||
type: CacheType = 'sessionStorage',
|
storageType: CacheType = 'sessionStorage',
|
||||||
|
defaultValue?: T,
|
||||||
): T | null => {
|
): T | null => {
|
||||||
|
try {
|
||||||
const data =
|
const data =
|
||||||
type === 'localStorage'
|
storageType === 'localStorage'
|
||||||
? window.localStorage.getItem(key)
|
? window.localStorage.getItem(key)
|
||||||
: window.sessionStorage.getItem(key)
|
: window.sessionStorage.getItem(key)
|
||||||
|
|
||||||
return Object.is(data, null) ? null : JSON.parse(data as string)
|
if (data === null) {
|
||||||
|
return defaultValue ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(data) as T
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to get stored data for key '${key}'`, error)
|
||||||
|
|
||||||
|
return defaultValue ?? null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +77,7 @@ export const getCache = <T>(
|
|||||||
* - all-sessionStorage: 删除所有 sessionStorage 缓存值
|
* - all-sessionStorage: 删除所有 sessionStorage 缓存值
|
||||||
* - all-localStorage: 删除所有 localStorage 缓存值
|
* - all-localStorage: 删除所有 localStorage 缓存值
|
||||||
*/
|
*/
|
||||||
export const removeCache = (
|
export const removeStorage = (
|
||||||
key: string | 'all' | 'all-sessionStorage' | 'all-localStorage',
|
key: string | 'all' | 'all-sessionStorage' | 'all-localStorage',
|
||||||
type: CacheType = 'sessionStorage',
|
type: CacheType = 'sessionStorage',
|
||||||
) => {
|
) => {
|
||||||
@ -78,6 +99,12 @@ export const removeCache = (
|
|||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (!key) {
|
||||||
|
console.error('Failed to remove stored data: key is empty or undefined')
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type === 'localStorage'
|
type === 'localStorage'
|
||||||
? window.localStorage.removeItem(key)
|
? window.localStorage.removeItem(key)
|
||||||
: window.sessionStorage.removeItem(key)
|
: window.sessionStorage.removeItem(key)
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { isValueType } from '@use-utils/hook'
|
import { isValueType } from '@use-utils/hook'
|
||||||
import { APP_REGEX } from '@/appConfig/regConfig'
|
import { APP_REGEX } from '@/appConfig/regConfig'
|
||||||
|
|
||||||
import type { EventListenerOrEventListenerObject } from '@/types/modules/utils'
|
import type {
|
||||||
|
EventListenerOrEventListenerObject,
|
||||||
|
PartialCSSStyleDeclaration,
|
||||||
|
ElementSelector,
|
||||||
|
} from '@/types/modules/utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -116,6 +120,8 @@ export const hasClass = (element: HTMLElement, className: string) => {
|
|||||||
* @param el Target element dom
|
* @param el Target element dom
|
||||||
* @param styles 所需绑定样式(如果为字符串, 则必须以分号结尾每个行内样式描述)
|
* @param styles 所需绑定样式(如果为字符串, 则必须以分号结尾每个行内样式描述)
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @example
|
||||||
* style of string
|
* style of string
|
||||||
* ```
|
* ```
|
||||||
* const styles = 'width: 100px; height: 100px; background: red;'
|
* const styles = 'width: 100px; height: 100px; background: red;'
|
||||||
@ -132,44 +138,56 @@ export const hasClass = (element: HTMLElement, className: string) => {
|
|||||||
* addStyle(styles)
|
* addStyle(styles)
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const addStyle = <K extends keyof CSSStyleDeclaration & string>(
|
export const addStyle = (
|
||||||
el: HTMLElement,
|
el: HTMLElement,
|
||||||
styles: K | Partial<CSSStyleDeclaration>,
|
styles: PartialCSSStyleDeclaration | string,
|
||||||
) => {
|
) => {
|
||||||
if (el) {
|
if (!el) {
|
||||||
if (isValueType<object>(styles, 'Object')) {
|
return
|
||||||
Object.keys(styles).forEach((item) => {
|
}
|
||||||
el.style[item] = styles[item]
|
|
||||||
})
|
|
||||||
} else if (isValueType<string>(styles, 'String')) {
|
|
||||||
const _styles = styles
|
|
||||||
|
|
||||||
_styles.split(';').forEach((item) => {
|
let styleObj: PartialCSSStyleDeclaration
|
||||||
const [_k, _v] = item.split(':')
|
|
||||||
|
|
||||||
if (_k && _v) {
|
if (isValueType<string>(styles, 'String')) {
|
||||||
el.style[_k.trim()] = _v.trim()
|
styleObj = styles.split(';').reduce((pre, curr) => {
|
||||||
|
const [key, value] = curr.split(':').map((s) => s.trim())
|
||||||
|
|
||||||
|
if (key && value) {
|
||||||
|
pre[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return pre
|
||||||
|
}, {} as PartialCSSStyleDeclaration)
|
||||||
|
} else {
|
||||||
|
styleObj = styles
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(styleObj).forEach((key) => {
|
||||||
|
const value = styleObj[key]
|
||||||
|
|
||||||
|
if (key in el.style) {
|
||||||
|
el.style[key] = value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param el Target element dom
|
* @param el Target element dom
|
||||||
* @param styles 所需卸载样式
|
* @param styles 所需卸载样式
|
||||||
*/
|
*/
|
||||||
export const removeStyle = <K extends keyof CSSStyleDeclaration & string>(
|
export const removeStyle = (
|
||||||
el: HTMLElement,
|
el: HTMLElement,
|
||||||
styles: K[],
|
styles: (keyof CSSStyleDeclaration & string)[],
|
||||||
) => {
|
) => {
|
||||||
if (el) {
|
if (!el) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
styles.forEach((curr) => {
|
styles.forEach((curr) => {
|
||||||
el.style.removeProperty(curr)
|
el.style.removeProperty(curr)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -222,33 +240,33 @@ export const colorToRgba = (color: string, alpha = 1) => {
|
|||||||
* 示例:
|
* 示例:
|
||||||
*
|
*
|
||||||
* class:
|
* class:
|
||||||
* const el = getElement('.demo')
|
* const el = getElements('.demo')
|
||||||
* id:
|
* id:
|
||||||
* const el = getElement('#demo')
|
* const el = getElements('#demo')
|
||||||
* attribute:
|
* attribute:
|
||||||
* const el = getElement('attr:type=button')
|
* const el = getElements('attr:type=button')
|
||||||
* 或者可以这样写
|
* 或者可以这样写
|
||||||
* const el = getElement('attr:type')
|
* const el = getElements('attr:type')
|
||||||
*/
|
*/
|
||||||
export const getElement = <T extends Element>(element: string) => {
|
export const getElements = <T extends Element = Element>(
|
||||||
if (!element) {
|
selector: ElementSelector,
|
||||||
|
) => {
|
||||||
|
if (!selector) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
let queryParam: string
|
const queryParam = selector.startsWith('attr:')
|
||||||
|
? `[${selector.replace('attr:', '')}]`
|
||||||
if (element.startsWith('attr:')) {
|
: selector
|
||||||
queryParam = '[' + element.replace('attr:', '') + ']'
|
|
||||||
} else {
|
|
||||||
queryParam = element
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const el = Array.from(document.querySelectorAll<T>(queryParam))
|
const elements = Array.from(document.querySelectorAll<T>(queryParam))
|
||||||
|
|
||||||
return el
|
return elements
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return []
|
console.error(`Failed to get elements for selector '${selector}'`, error)
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { NForm, NFormItem, NInput, NButton, NSpace, NDivider } from 'naive-ui'
|
import { NForm, NFormItem, NInput, NButton, NSpace, NDivider } from 'naive-ui'
|
||||||
|
|
||||||
import { setCache } from '@/utils/cache'
|
import { setStorage } from '@/utils/cache'
|
||||||
import { setSpin } from '@/spin'
|
import { setSpin } from '@/spin'
|
||||||
import { useSignin } from '@/store'
|
import { useSignin } from '@/store'
|
||||||
import { useI18n } from '@/locales/useI18n'
|
import { useI18n } from '@/locales/useI18n'
|
||||||
@ -55,8 +55,8 @@ const Signin = defineComponent({
|
|||||||
|
|
||||||
window.$message.success(`欢迎${signinForm.value.name}登陆~`)
|
window.$message.success(`欢迎${signinForm.value.name}登陆~`)
|
||||||
|
|
||||||
setCache(APP_CATCH_KEY.token, 'tokenValue')
|
setStorage(APP_CATCH_KEY.token, 'tokenValue')
|
||||||
setCache(APP_CATCH_KEY.signin, res.data)
|
setStorage(APP_CATCH_KEY.signin, res.data)
|
||||||
|
|
||||||
router.push(path)
|
router.push(path)
|
||||||
}, 2 * 1000)
|
}, 2 * 1000)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user