refactor: 统一代码风格 (if 语句 & 箭头函数)

This commit is contained in:
pany 2024-11-25 17:26:27 +08:00
parent 9b359203fc
commit 0f5f16cf0f
39 changed files with 188 additions and 135 deletions

View File

@ -9,6 +9,7 @@ const { initGreyAndColorWeakness } = useGreyAndColorWeakness()
//
initTheme()
//
initGreyAndColorWeakness()

View File

@ -1,7 +1,7 @@
/**
* dark-blue 主题模式下的 Element Plus CSS 变量
* 在此查阅所有可自定义的变量https://github.com/element-plus/element-plus/blob/dev/packages/theme-chalk/src/common/var.scss
* 也可以打开浏览器控制台选择元素查看要覆盖的变量名
* @description dark-blue 主题模式下的 Element Plus CSS 变量
* @description 在此查阅所有可自定义的变量https://github.com/element-plus/element-plus/blob/dev/packages/theme-chalk/src/common/var.scss
* @description 也可以打开浏览器控制台选择元素查看要覆盖的变量名
*/
/* 基础颜色 */

View File

@ -1,7 +1,7 @@
/**
* 所有主题模式下的 Vxe Table CSS 变量
* Element Plus CSS 变量来覆写 Vxe Table CSS 变量目的是使 Vxe Table 支持多主题模式且样式统一
* 在此查阅所有可自定义的变量https://github.com/x-extends/vxe-table/blob/master/styles/css-variable.scss
* @description 所有主题模式下的 Vxe Table CSS 变量
* @description Element Plus CSS 变量来覆写 Vxe Table CSS 变量目的是使 Vxe Table 支持多主题模式且样式统一
* @description 在此查阅所有可自定义的变量https://github.com/x-extends/vxe-table/blob/master/styles/css-variable.scss
*/
:root {

View File

@ -16,12 +16,16 @@ interface DataItem {
/** 角标当前值 */
const badgeValue = computed(() => data.value.reduce((sum, item) => sum + item.list.length, 0))
/** 角标最大值 */
const badgeMax = 99
/** 面板宽度 */
const popoverWidth = 350
/** 当前 Tab */
const activeName = ref<TabName>("通知")
/** 所有数据 */
const data = ref<DataItem[]>([
//

View File

@ -22,7 +22,9 @@ const props = withDefaults(defineProps<Props>(), {
})
const CONTENT_LARGE = "content-large"
const CONTENT_FULL = "content-full"
const classList = document.body.classList
// #region
@ -35,17 +37,21 @@ function handleFullscreenClick() {
const dom = document.querySelector(props.element) || undefined
isEnabled ? screenfull.toggle(dom) : ElMessage.warning("您的浏览器无法工作")
}
function handleFullscreenChange() {
isFullscreen.value = screenfull.isFullscreen
// 退 class
isFullscreen.value || classList.remove(CONTENT_LARGE, CONTENT_FULL)
}
watchEffect((onCleanup) => {
if (isEnabled) {
//
screenfull.on("change", handleFullscreenChange)
//
onCleanup(() => screenfull.off("change", handleFullscreenChange))
onCleanup(() => {
screenfull.off("change", handleFullscreenChange)
})
}
})
// #endregion
@ -54,11 +60,13 @@ watchEffect((onCleanup) => {
const isContentLarge = ref<boolean>(false)
const contentLargeTips = computed(() => (isContentLarge.value ? "内容区复原" : "内容区放大"))
const contentLargeSvgName = computed(() => (isContentLarge.value ? "fullscreen-exit" : "fullscreen"))
function handleContentLargeClick() {
isContentLarge.value = !isContentLarge.value
//
classList.toggle(CONTENT_LARGE, isContentLarge.value)
}
function handleContentFullClick() {
//
isContentLarge.value && handleContentLargeClick()

View File

@ -130,7 +130,7 @@ function handleEnter() {
try {
router.push({ name })
} catch {
return ElMessage.error("该菜单有必填的动态参数,无法通过搜索进入")
return ElMessage.warning("该菜单有必填的动态参数,无法通过搜索进入")
}
handleClose()
}

View File

@ -8,10 +8,12 @@ interface Props {
}
const props = defineProps<Props>()
/** 选中的菜单 */
const modelValue = defineModel<RouteRecordName | undefined>({ required: true })
const instance = getCurrentInstance()
const scrollbarHeight = ref<number>(0)
/** 菜单的样式 */
@ -47,13 +49,19 @@ function getScrollTop(index: number) {
}
//
onBeforeMount(() => window.addEventListener("resize", getScrollbarHeight))
onBeforeMount(() => {
window.addEventListener("resize", getScrollbarHeight)
})
//
onMounted(() => getScrollbarHeight())
onMounted(() => {
getScrollbarHeight()
})
//
onBeforeUnmount(() => window.removeEventListener("resize", getScrollbarHeight))
onBeforeUnmount(() => {
window.removeEventListener("resize", getScrollbarHeight)
})
defineExpose({ getScrollTop })
</script>

View File

@ -14,7 +14,9 @@ function handleChangeTheme({ clientX, clientY }: MouseEvent, themeName: ThemeNam
style.setProperty("--v3-theme-x", `${clientX}px`)
style.setProperty("--v3-theme-y", `${clientY}px`)
style.setProperty("--v3-theme-r", `${maxRadius}px`)
const handler = () => setTheme(themeName)
const handler = () => {
setTheme(themeName)
}
document.startViewTransition ? document.startViewTransition(handler) : handler()
}
</script>

View File

@ -3,6 +3,7 @@ import { useAppStore } from "@/pinia/stores/app"
import { computed } from "vue"
const appStore = useAppStore()
const isMobile = computed(() => appStore.device === DeviceEnum.Mobile)
const isDesktop = computed(() => appStore.device === DeviceEnum.Desktop)

View File

@ -29,16 +29,16 @@ export function useFetchSelect(props: FetchSelectProps) {
const loadData = () => {
loading.value = true
options.value = []
api()
.then((res) => {
options.value = res.data
})
.finally(() => {
loading.value = false
})
api().then((res) => {
options.value = res.data
}).finally(() => {
loading.value = false
})
}
onMounted(() => loadData())
onMounted(() => {
loadData()
})
return { loading, options, value }
}

View File

@ -3,6 +3,7 @@ import { watchEffect } from "vue"
const GREY_MODE = "grey-mode"
const COLOR_WEAKNESS = "color-weakness"
const classList = document.documentElement.classList
/** 初始化 */

View File

@ -3,6 +3,7 @@ import { useSettingsStore } from "@/pinia/stores/settings"
import { computed } from "vue"
const settingsStore = useSettingsStore()
const isLeft = computed(() => settingsStore.layoutMode === LayoutModeEnum.Left)
const isTop = computed(() => settingsStore.layoutMode === LayoutModeEnum.Top)
const isLeftTop = computed(() => settingsStore.layoutMode === LayoutModeEnum.LeftTop)

View File

@ -6,7 +6,9 @@ import { onBeforeUnmount } from "vue"
type Callback = (route: RouteLocationNormalized) => void
const emitter = mitt()
const key = Symbol("ROUTE_CHANGE")
let latestRoute: RouteLocationNormalized
/** 设置最新的路由信息,触发路由变化事件 */
@ -18,9 +20,9 @@ export function setRouteChange(to: RouteLocationNormalized) {
}
/**
* Composable
* 1. watch
* 2. 使
* @name Composable
* @description 1. watch
* @description 2. 使
*/
export function useRouteListener() {
// 回调函数集合
@ -43,9 +45,7 @@ export function useRouteListener() {
// 组件销毁前移除监听器
onBeforeUnmount(() => {
for (let i = 0; i < callbackList.length; i++) {
removeRouteListener(callbackList[i])
}
callbackList.forEach(removeRouteListener)
})
return { listenerRouteChange, removeRouteListener }

View File

@ -2,14 +2,6 @@ import type { Ref } from "vue"
import { debounce } from "lodash-es"
import { onBeforeUnmount, ref } from "vue"
interface Observer {
watermarkElMutationObserver?: MutationObserver
parentElMutationObserver?: MutationObserver
parentElResizeObserver?: ResizeObserver
}
type DefaultConfig = typeof DEFAULT_CONFIG
/** 默认配置 */
const DEFAULT_CONFIG = {
/** 防御(默认开启,能防御水印被删除或隐藏,但可能会有性能损耗) */
@ -30,13 +22,21 @@ const DEFAULT_CONFIG = {
height: 200
}
type DefaultConfig = typeof DEFAULT_CONFIG
interface Observer {
watermarkElMutationObserver?: MutationObserver
parentElMutationObserver?: MutationObserver
parentElResizeObserver?: ResizeObserver
}
/** body 元素 */
const bodyEl = ref<HTMLElement>(document.body)
/**
* Composable
* 1. body
* 2.
* @name Composable
* @description 1. body
* @description 2.
*/
export function useWatermark(parentEl: Ref<HTMLElement | null> = bodyEl) {
// 备份文本
@ -226,7 +226,9 @@ export function useWatermark(parentEl: Ref<HTMLElement | null> = bodyEl) {
}
// 在组件卸载前移除水印以及各种监听
onBeforeUnmount(() => clearWatermark())
onBeforeUnmount(() => {
clearWatermark()
})
return { setWatermark, clearWatermark }
}

View File

@ -1,21 +1,22 @@
/** 路由配置 */
interface RouteSettings {
/**
*
* 1. roles
* 2. dynamic: false
* @name
* @description 1. roles
* @description 2. dynamic: false
*/
dynamic: boolean
/**
*
* 1. 访
* 2.
* @name
* @description
* @description 1. 访
* @description 2.
*/
defaultRoles: Array<string>
/**
*
* 1.
* 2.
* @name
* @description 1.
* @description 2.
*/
thirdLevelRouteCache: boolean
}

View File

@ -13,8 +13,10 @@ export enum LayoutModeEnum {
/** 侧边栏打开状态常量 */
export const SIDEBAR_OPENED = "opened"
/** 侧边栏关闭状态常量 */
export const SIDEBAR_CLOSED = "closed"
export type SidebarOpened = typeof SIDEBAR_OPENED
export type SidebarClosed = typeof SIDEBAR_CLOSED

View File

@ -2,7 +2,10 @@ import type { Directive } from "vue"
import { useUserStore } from "@/pinia/stores/user"
import { isArray } from "@/utils/validate"
/** 权限指令,和权限判断函数 checkPermission 功能类似 */
/**
* @name
* @description checkPermission
*/
export const permission: Directive = {
mounted(el, binding) {
const { value: permissionRoles } = binding

View File

@ -88,8 +88,6 @@ function createInstance() {
case 505:
error.message = "HTTP 版本不受支持"
break
default:
break
}
ElMessage.error(error.message)
return Promise.reject(error)

View File

@ -6,7 +6,9 @@ import { ref } from "vue"
import { useRoute, useRouter } from "vue-router"
const route = useRoute()
const router = useRouter()
const { listenerRouteChange } = useRouteListener()
/** 定义响应式数据 breadcrumbs用于存储面包屑导航信息 */
@ -26,10 +28,7 @@ function pathCompile(path: string) {
/** 处理面包屑导航点击事件 */
function handleLink(item: RouteLocationMatched) {
const { redirect, path } = item
if (redirect) {
router.push(redirect as string)
return
}
if (redirect) return router.push(redirect as string)
router.push(pathCompile(path))
}

View File

@ -11,6 +11,7 @@ const props = withDefaults(defineProps<Props>(), {
})
const buttonTopCss = `${props.buttonTop}px`
const show = ref(false)
</script>

View File

@ -8,6 +8,7 @@ import { watchEffect } from "vue"
import SelectLayoutMode from "./SelectLayoutMode.vue"
const { isLeft } = useLayoutMode()
const settingsStore = useSettingsStore()
// 使 storeToRefs

View File

@ -18,14 +18,10 @@ const props = withDefaults(defineProps<Props>(), {
const alwaysShowRootMenu = computed(() => props.item.meta?.alwaysShow)
/** 显示的子菜单 */
const showingChildren = computed(() => {
return props.item.children?.filter(child => !child.meta?.hidden) ?? []
})
const showingChildren = computed(() => props.item.children?.filter(child => !child.meta?.hidden) ?? [])
/** 显示的子菜单数量 */
const showingChildNumber = computed(() => {
return showingChildren.value.length
})
const showingChildNumber = computed(() => showingChildren.value.length)
/** 唯一的子菜单项 */
const theOnlyOneChild = computed(() => {

View File

@ -21,28 +21,16 @@ const appStore = useAppStore()
const permissionStore = usePermissionStore()
const settingsStore = useSettingsStore()
const activeMenu = computed(() => {
const {
meta: { activeMenu },
path
} = route
return activeMenu || path
})
const activeMenu = computed(() => route.meta.activeMenu || route.path)
const noHiddenRoutes = computed(() => permissionStore.routes.filter(item => !item.meta?.hidden))
const isCollapse = computed(() => !appStore.sidebar.opened)
const isLogo = computed(() => isLeft.value && settingsStore.showLogo)
const backgroundColor = computed(() => (isLeft.value ? v3SidebarMenuBgColor : undefined))
const textColor = computed(() => (isLeft.value ? v3SidebarMenuTextColor : undefined))
const activeTextColor = computed(() => (isLeft.value ? v3SidebarMenuActiveTextColor : undefined))
const sidebarMenuItemHeight = computed(() => {
return !isTop.value ? "var(--v3-sidebar-menu-item-height)" : "var(--v3-navigationbar-height)"
})
const sidebarMenuHoverBgColor = computed(() => {
return !isTop.value ? "var(--v3-sidebar-menu-hover-bg-color)" : "transparent"
})
const tipLineWidth = computed(() => {
return !isTop.value ? "2px" : "0px"
})
const sidebarMenuItemHeight = computed(() => !isTop.value ? "var(--v3-sidebar-menu-item-height)" : "var(--v3-navigationbar-height)")
const sidebarMenuHoverBgColor = computed(() => !isTop.value ? "var(--v3-sidebar-menu-hover-bg-color)" : "transparent")
const tipLineWidth = computed(() => !isTop.value ? "2px" : "0px")
</script>
<template>

View File

@ -15,16 +15,20 @@ interface Props {
const props = defineProps<Props>()
const route = useRoute()
const settingsStore = useSettingsStore()
const { listenerRouteChange } = useRouteListener()
/** 滚动条组件元素的引用 */
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
/** 滚动条内容元素的引用 */
const scrollbarContentRef = ref<HTMLDivElement>()
/** 当前滚动条距离左边的距离 */
let currentScrollLeft = 0
/** 每次滚动距离 */
const translateDistance = 200

View File

@ -11,9 +11,13 @@ import { useRoute, useRouter } from "vue-router"
import ScrollPane from "./ScrollPane.vue"
const router = useRouter()
const route = useRoute()
const tagsViewStore = useTagsViewStore()
const permissionStore = usePermissionStore()
const { listenerRouteChange } = useRouteListener()
/** 标签页组件元素的引用数组 */
@ -21,12 +25,16 @@ const tagRefs = ref<InstanceType<typeof RouterLink>[]>([])
/** 右键菜单的状态 */
const visible = ref(false)
/** 右键菜单的 top 位置 */
const top = ref(0)
/** 右键菜单的 left 位置 */
const left = ref(0)
/** 当前正在右键操作的标签页 */
const selectedTag = ref<TagView>({})
/** 固定的标签页 */
let affixTags: TagView[] = []

View File

@ -10,7 +10,7 @@ const MAX_MOBILE_WIDTH = 992
* @name Composable
* @description Layout
*/
export default () => {
export function useResize() {
const appStore = useAppStore()
const { listenerRouteChange } = useRouteListener()

View File

@ -7,7 +7,7 @@ import { getCssVar, setCssVar } from "@/utils/css"
import { storeToRefs } from "pinia"
import { watchEffect } from "vue"
import { RightPanel, Settings } from "./components"
import useResize from "./composables/useResize"
import { useResize } from "./composables/useResize"
import LeftMode from "./LeftMode.vue"
import LeftTopMode from "./LeftTopMode.vue"
import TopMode from "./TopMode.vue"

View File

@ -20,6 +20,7 @@ const app = createApp(App)
// 加载插件
loadPlugins(app)
// 加载自定义指令
loadDirectives(app)

View File

@ -5,12 +5,14 @@ import ThemeSwitch from "@/components/ThemeSwitch/index.vue"
import { getLoginCodeApi } from "@/http/login"
import { useUserStore } from "@/pinia/stores/user"
import { Key, Loading, Lock, Picture, User } from "@element-plus/icons-vue"
import { ElMessage } from "element-plus"
import { reactive, ref } from "vue"
import { useRouter } from "vue-router"
import Owl from "./components/Owl.vue"
import { useFocus } from "./composables/useFocus"
const router = useRouter()
const { isFocus, handleBlur, handleFocus } = useFocus()
/** 登录表单元素的引用 */
@ -18,51 +20,57 @@ const loginFormRef = ref<FormInstance | null>(null)
/** 登录按钮 Loading */
const loading = ref(false)
/** 验证码图片 URL */
const codeUrl = ref("")
/** 登录表单数据 */
const loginFormData: LoginRequestData = reactive({
username: "admin",
password: "12345678",
code: ""
})
/** 登录表单校验规则 */
const loginFormRules: FormRules = {
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
username: [
{ required: true, message: "请输入用户名", trigger: "blur" }
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 8, max: 16, message: "长度在 8 到 16 个字符", trigger: "blur" }
],
code: [{ required: true, message: "请输入验证码", trigger: "blur" }]
code: [
{ required: true, message: "请输入验证码", trigger: "blur" }
]
}
/** 登录逻辑 */
/** 登录 */
function handleLogin() {
loginFormRef.value?.validate((valid: boolean, fields) => {
if (valid) {
loading.value = true
useUserStore()
.login(loginFormData)
.then(() => {
router.push({ path: "/" })
})
.catch(() => {
createCode()
loginFormData.password = ""
})
.finally(() => {
loading.value = false
})
} else {
console.error("表单校验不通过", fields)
loginFormRef.value?.validate((valid) => {
if (!valid) {
ElMessage.error("表单校验不通过")
return
}
loading.value = true
useUserStore().login(loginFormData).then(() => {
router.push({ path: "/" })
}).catch(() => {
createCode()
loginFormData.password = ""
}).finally(() => {
loading.value = false
})
})
}
/** 创建验证码 */
function createCode() {
//
//
loginFormData.code = ""
//
//
codeUrl.value = ""
//
getLoginCodeApi().then((res) => {
codeUrl.value = res.data
})

View File

@ -3,7 +3,9 @@ import { useUserStore } from "@/pinia/stores/user"
import { ref, watch } from "vue"
const userStore = useUserStore()
const switchRoles = ref(userStore.roles[0])
watch(switchRoles, (value) => {
userStore.changeRoles(value)
})

View File

@ -30,19 +30,20 @@ const formRules: FormRules<CreateOrUpdateTableRequestData> = {
password: [{ required: true, trigger: "blur", message: "请输入密码" }]
}
function handleCreateOrUpdate() {
formRef.value?.validate((valid: boolean, fields) => {
if (!valid) return console.error("表单校验不通过", fields)
formRef.value?.validate((valid) => {
if (!valid) {
ElMessage.error("表单校验不通过")
return
}
loading.value = true
const api = formData.value.id === undefined ? createTableDataApi : updateTableDataApi
api(formData.value)
.then(() => {
ElMessage.success("操作成功")
dialogVisible.value = false
getTableData()
})
.finally(() => {
loading.value = false
})
api(formData.value).then(() => {
ElMessage.success("操作成功")
dialogVisible.value = false
getTableData()
}).finally(() => {
loading.value = false
})
})
}
function resetForm() {
@ -87,17 +88,14 @@ function getTableData() {
size: paginationData.pageSize,
username: searchData.username || undefined,
phone: searchData.phone || undefined
}).then(({ data }) => {
paginationData.total = data.total
tableData.value = data.list
}).catch(() => {
tableData.value = []
}).finally(() => {
loading.value = false
})
.then(({ data }) => {
paginationData.total = data.total
tableData.value = data.list
})
.catch(() => {
tableData.value = []
})
.finally(() => {
loading.value = false
})
}
function handleSearch() {
paginationData.currentPage === 1 ? getTableData() : (paginationData.currentPage = 1)

View File

@ -20,13 +20,16 @@ export const useAppStore = defineStore("app", () => {
opened: getSidebarStatus() !== SIDEBAR_CLOSED,
withoutAnimation: false
})
// 设备类型
const device = ref<DeviceEnum>(DeviceEnum.Desktop)
// 监听侧边栏 opened 状态
watch(
() => sidebar.opened,
opened => handleSidebarStatus(opened)
(opened) => {
handleSidebarStatus(opened)
}
)
// 切换侧边栏
@ -34,11 +37,13 @@ export const useAppStore = defineStore("app", () => {
sidebar.opened = !sidebar.opened
sidebar.withoutAnimation = withoutAnimation
}
// 关闭侧边栏
const closeSidebar = (withoutAnimation: boolean) => {
sidebar.opened = false
sidebar.withoutAnimation = withoutAnimation
}
// 切换设备类型
const toggleDevice = (value: DeviceEnum) => {
device.value = value

View File

@ -28,6 +28,7 @@ function filterDynamicRoutes(routes: RouteRecordRaw[], roles: string[]) {
export const usePermissionStore = defineStore("permission", () => {
// 可访问的路由
const routes = ref<RouteRecordRaw[]>([])
// 有访问权限的动态路由
const addRoutes = ref<RouteRecordRaw[]>([])

View File

@ -34,20 +34,26 @@ export const useTagsViewStore = defineStore("tags-view", () => {
const addCachedView = (view: TagView) => {
if (typeof view.name !== "string") return
if (cachedViews.value.includes(view.name)) return
if (view.meta?.keepAlive) cachedViews.value.push(view.name)
if (view.meta?.keepAlive) {
cachedViews.value.push(view.name)
}
}
// #endregion
// #region del
const delVisitedView = (view: TagView) => {
const index = visitedViews.value.findIndex(v => v.path === view.path)
if (index !== -1) visitedViews.value.splice(index, 1)
if (index !== -1) {
visitedViews.value.splice(index, 1)
}
}
const delCachedView = (view: TagView) => {
if (typeof view.name !== "string") return
const index = cachedViews.value.indexOf(view.name)
if (index !== -1) cachedViews.value.splice(index, 1)
if (index !== -1) {
cachedViews.value.splice(index, 1)
}
}
// #endregion

View File

@ -23,6 +23,7 @@ export const useUserStore = defineStore("user", () => {
setToken(data.token)
token.value = data.token
}
// 获取用户详情
const getInfo = async () => {
const { data } = await getUserInfoApi()
@ -30,6 +31,7 @@ export const useUserStore = defineStore("user", () => {
// 验证返回的 roles 是否为一个非空数组,否则塞入一个没有任何作用的默认角色,防止路由守卫逻辑进入无限循环
roles.value = data.roles?.length > 0 ? data.roles : routeSettings.defaultRoles
}
// 模拟角色变化
const changeRoles = async (role: string) => {
const newToken = `token-${role}`
@ -38,6 +40,7 @@ export const useUserStore = defineStore("user", () => {
// 用刷新页面代替重新登录
window.location.reload()
}
// 登出
const logout = () => {
removeToken()
@ -46,12 +49,14 @@ export const useUserStore = defineStore("user", () => {
resetRouter()
_resetTagsView()
}
// 重置 Token
const resetToken = () => {
removeToken()
token.value = ""
roles.value = []
}
// 重置 Visited Views 和 Cached Views
const _resetTagsView = () => {
if (!settingsStore.cacheTagsView) {

View File

@ -20,10 +20,8 @@ export function flatMultiLevelRoutes(routes: RouteRecordRaw[]) {
/** 判断路由层级是否大于 2 */
function isMultipleRoute(route: RouteRecordRaw) {
const children = route.children
if (children?.length) {
// 只要有一个子路由的 children 长度大于 0就说明是三级及其以上路由
return children.some(child => child.children?.length)
}
// 只要有一个子路由的 children 长度大于 0就说明是三级及其以上路由
if (children?.length) return children.some(child => child.children?.length)
return false
}

View File

@ -26,9 +26,7 @@ router.beforeEach(async (to, _from, next) => {
}
// 如果已经登录,并准备进入 Login 页面,则重定向到主页
if (to.path === "/login") {
return next({ path: "/" })
}
if (to.path === "/login") return next({ path: "/" })
// 如果用户已经获得其权限角色
if (userStore.roles.length !== 0) return next()
@ -47,7 +45,7 @@ router.beforeEach(async (to, _from, next) => {
} catch (error) {
// 过程中发生任何错误,都直接重置 Token并重定向到登录页面
userStore.resetToken()
ElMessage.error((error as Error).message || "路由守卫过程发生错误")
ElMessage.error((error as Error).message || "路由守卫发生错误")
next("/login")
}
})

View File

@ -6,9 +6,11 @@ import Cookies from "js-cookie"
export function getToken() {
return Cookies.get(CacheKey.TOKEN)
}
export function setToken(token: string) {
Cookies.set(CacheKey.TOKEN, token)
}
export function removeToken() {
Cookies.remove(CacheKey.TOKEN)
}

View File

@ -1,7 +1,7 @@
/** 获取指定元素(默认全局)上的 CSS 变量的值 */
export function getCssVar(varName: string, element: HTMLElement = document.documentElement) {
if (!varName?.startsWith("--")) {
console.warn("CSS 变量名应以 '--' 开头")
console.error("CSS 变量名应以 '--' 开头")
return ""
}
// 没有拿到值时,会返回空串
@ -11,7 +11,7 @@ export function getCssVar(varName: string, element: HTMLElement = document.docum
/** 设置指定元素(默认全局)上的 CSS 变量的值 */
export function setCssVar(varName: string, value: string, element: HTMLElement = document.documentElement) {
if (!varName?.startsWith("--")) {
console.warn("CSS 变量名应以 '--' 开头")
console.error("CSS 变量名应以 '--' 开头")
return
}
element.style.setProperty(varName, value)