chore: format code

This commit is contained in:
vben
2024-06-09 13:31:43 +08:00
parent 68229a4d2f
commit 35c3dd78ec
65 changed files with 419 additions and 494 deletions

View File

@@ -3,6 +3,7 @@ dist
.output.js .output.js
node_modules node_modules
.nvmrc .nvmrc
coverage
**/*.svg **/*.svg

View File

@@ -1,3 +1,4 @@
dist dist
public public
__tests__ __tests__
coverage

View File

@@ -96,16 +96,16 @@ function handleNoticeClear() {
<UserDropdown <UserDropdown
:avatar="preferences.app.defaultAvatar" :avatar="preferences.app.defaultAvatar"
:menus="menus" :menus="menus"
text="Vben Admin"
description="ann.vben@gmail.com" description="ann.vben@gmail.com"
tag-text="Pro" tag-text="Pro"
text="Vben Admin"
@logout="handleLogout" @logout="handleLogout"
/> />
</template> </template>
<template #notification> <template #notification>
<Notification <Notification
dot
:notifications="notifications" :notifications="notifications"
dot
@clear="handleNoticeClear" @clear="handleNoticeClear"
/> />
</template> </template>

View File

@@ -69,9 +69,9 @@ const loginLoading = computed(() => {
<template> <template>
<AuthenticationLogin <AuthenticationLogin
username-placeholder="vben"
password-placeholder="123456"
:loading="loginLoading" :loading="loginLoading"
password-placeholder="123456"
username-placeholder="vben"
@submit="handleLogin" @submit="handleLogin"
/> />
</template> </template>

View File

@@ -3,5 +3,5 @@ import { Fallback } from '@vben/common-ui';
</script> </script>
<template> <template>
<Fallback status="500" :show-back="false" /> <Fallback :show-back="false" status="500" />
</template> </template>

View File

@@ -81,7 +81,41 @@ export async function perfectionist(): Promise<Linter.FlatConfig[]> {
type: 'natural', type: 'natural',
}, },
], ],
'perfectionist/sort-vue-attributes': 'off', 'perfectionist/sort-vue-attributes': [
'error',
{
// Based on: https://vuejs.org/style-guide/rules-recommended.html#element-attribute-order
'custom-groups': {
/* eslint-disable perfectionist/sort-objects */
DEFINITION: '*(is|:is|v-is)',
LIST_RENDERING: 'v-for',
CONDITIONALS: 'v-*(else-if|if|else|show|cloak)',
RENDER_MODIFIERS: 'v-*(pre|once)',
GLOBAL: '*(:id|id)',
UNIQUE: '*(ref|key|:ref|:key)',
SLOT: '*(v-slot|slot)',
TWO_WAY_BINDING: '*(v-model|v-model:*)',
// OTHER_DIRECTIVES e.g. 'v-custom-directive'
EVENTS: '*(v-on|@*)',
CONTENT: 'v-*(html|text)',
/* eslint-enable perfectionist/sort-objects */
},
groups: [
'DEFINITION',
'LIST_RENDERING',
'CONDITIONALS',
'RENDER_MODIFIERS',
'GLOBAL',
'UNIQUE',
'SLOT',
'TWO_WAY_BINDING',
'unknown',
'EVENTS',
'CONTENT',
],
type: 'natural',
},
],
}, },
}, },
]; ];

View File

@@ -65,8 +65,8 @@ const style = computed((): CSSProperties => {
<template> <template>
<footer <footer
:class="b()" :class="b()"
class="bottom-0 w-full transition-all duration-200"
:style="style" :style="style"
class="bottom-0 w-full transition-all duration-200"
> >
<slot></slot> <slot></slot>
</footer> </footer>

View File

@@ -267,7 +267,7 @@ function handleScroll(event: Event) {
<div v-if="slots.logo" :style="headerStyle"> <div v-if="slots.logo" :style="headerStyle">
<slot name="logo"></slot> <slot name="logo"></slot>
</div> </div>
<ScrollArea :style="contentStyle" :on-scroll="handleScroll"> <ScrollArea :on-scroll="handleScroll" :style="contentStyle">
<div :class="[e('shadow'), { scrolled }]"></div> <div :class="[e('shadow'), { scrolled }]"></div>
<slot></slot> <slot></slot>
</ScrollArea> </ScrollArea>
@@ -282,8 +282,8 @@ function handleScroll(event: Event) {
v-if="isSideMixed" v-if="isSideMixed"
ref="asideRef" ref="asideRef"
:class="e('extra')" :class="e('extra')"
class="transition-[width] duration-200"
:style="extraStyle" :style="extraStyle"
class="transition-[width] duration-200"
> >
<SideCollapseButton <SideCollapseButton
v-if="isSideMixed && expandOnHover" v-if="isSideMixed && expandOnHover"
@@ -300,9 +300,9 @@ function handleScroll(event: Event) {
<slot name="extra-title"></slot> <slot name="extra-title"></slot>
</div> </div>
<ScrollArea <ScrollArea
:style="extraContentStyle"
:class="e('extra-content')" :class="e('extra-content')"
:on-scroll="handleScroll" :on-scroll="handleScroll"
:style="extraContentStyle"
> >
<div :class="[e('shadow'), { scrolled }]"></div> <div :class="[e('shadow'), { scrolled }]"></div>
<slot name="extra"></slot> <slot name="extra"></slot>

View File

@@ -46,6 +46,11 @@ interface VbenLayoutProps {
* @default #fff * @default #fff
*/ */
footerBackgroundColor?: string; footerBackgroundColor?: string;
/**
* footer 是否可见
* @default false
*/
footerEnable?: boolean;
/** /**
* footer 是否固定 * footer 是否固定
* @default true * @default true
@@ -56,11 +61,6 @@ interface VbenLayoutProps {
* @default 32 * @default 32
*/ */
footerHeight?: number; footerHeight?: number;
/**
* footer 是否可见
* @default false
*/
footerVisible?: boolean;
/** /**
* 背景颜色 * 背景颜色
* @default #fff * @default #fff

View File

@@ -26,10 +26,10 @@ const props = withDefaults(defineProps<Props>(), {
contentPaddingLeft: 0, contentPaddingLeft: 0,
contentPaddingRight: 0, contentPaddingRight: 0,
contentPaddingTop: 0, contentPaddingTop: 0,
footerEnable: false,
// footerBackgroundColor: '#fff', // footerBackgroundColor: '#fff',
footerFixed: true, footerFixed: true,
footerHeight: 32, footerHeight: 32,
footerVisible: false,
// headerBackgroundColor: 'hsl(var(--color-background))', // headerBackgroundColor: 'hsl(var(--color-background))',
headerHeight: 50, headerHeight: 50,
headerHeightOffset: 10, headerHeightOffset: 10,
@@ -323,7 +323,7 @@ const contentStyle = computed((): CSSProperties => {
(!isHeaderAuto.value || scrollY.value < headerWrapperHeight.value) (!isHeaderAuto.value || scrollY.value < headerWrapperHeight.value)
? `${headerWrapperHeight.value}px` ? `${headerWrapperHeight.value}px`
: 0, : 0,
paddingBottom: `${props.footerVisible ? props.footerHeight : 0}px`, paddingBottom: `${props.footerEnable ? props.footerHeight : 0}px`,
}; };
}); });
@@ -465,19 +465,19 @@ function handleOpenMenu() {
<LayoutSide <LayoutSide
v-if="sideVisibleState" v-if="sideVisibleState"
v-model:collapse="sideCollapse" v-model:collapse="sideCollapse"
v-model:extra-collapse="sideExtraCollapse"
v-model:expand-on-hovering="sideExpandOnHovering"
v-model:expand-on-hover="sideExpandOnHover" v-model:expand-on-hover="sideExpandOnHover"
v-model:expand-on-hovering="sideExpandOnHovering"
v-model:extra-collapse="sideExtraCollapse"
v-model:extra-visible="sideExtraVisible" v-model:extra-visible="sideExtraVisible"
:dom-visible="!isMobile"
:fixed-extra="sideExpandOnHover"
:mixed-width="sideMixedWidth"
:header-height="isMixedNav ? 0 : getHeaderHeight"
:collapse-width="getSideCollapseWidth" :collapse-width="getSideCollapseWidth"
:dom-visible="!isMobile"
:extra-width="getExtraWidth"
:fixed-extra="sideExpandOnHover"
:header-height="isMixedNav ? 0 : getHeaderHeight"
:is-side-mixed="isSideMixedNav" :is-side-mixed="isSideMixedNav"
:mixed-width="sideMixedWidth"
:padding-top="sidePaddingTop" :padding-top="sidePaddingTop"
:show="showSide" :show="showSide"
:extra-width="getExtraWidth"
:width="getSideWidth" :width="getSideWidth"
:z-index="sideZIndex" :z-index="sideZIndex"
v-bind="sideFace" v-bind="sideFace"
@@ -513,16 +513,16 @@ function handleOpenMenu() {
v-if="headerVisible" v-if="headerVisible"
:full-width="!isSideMode" :full-width="!isSideMode"
:height="getHeaderHeight" :height="getHeaderHeight"
:show="!fullContent && !headerHidden"
:side-hidden="sideHidden"
:show-toggle-btn="showHeaderToggleButton"
:width="mainStyle.width"
:is-mixed-nav="isMixedNav" :is-mixed-nav="isMixedNav"
:is-mobile="isMobile" :is-mobile="isMobile"
:z-index="headerZIndex" :show="!fullContent && !headerHidden"
:show-toggle-btn="showHeaderToggleButton"
:side-hidden="sideHidden"
:side-width="sideWidth" :side-width="sideWidth"
@toggle-menu="handleToggleMenu" :width="mainStyle.width"
:z-index="headerZIndex"
@open-menu="handleOpenMenu" @open-menu="handleOpenMenu"
@toggle-menu="handleToggleMenu"
> >
<template v-if="showHeaderLogo" #logo> <template v-if="showHeaderLogo" #logo>
<slot name="logo"></slot> <slot name="logo"></slot>
@@ -540,8 +540,6 @@ function handleOpenMenu() {
<!-- </div> --> <!-- </div> -->
<LayoutContent <LayoutContent
class="transition-[margin-top] duration-200"
:style="contentStyle"
:content-compact="contentCompact" :content-compact="contentCompact"
:content-compact-width="contentCompactWidth" :content-compact-width="contentCompactWidth"
:padding="contentPadding" :padding="contentPadding"
@@ -549,12 +547,14 @@ function handleOpenMenu() {
:padding-left="contentPaddingLeft" :padding-left="contentPaddingLeft"
:padding-right="contentPaddingRight" :padding-right="contentPaddingRight"
:padding-top="contentPaddingTop" :padding-top="contentPaddingTop"
:style="contentStyle"
class="transition-[margin-top] duration-200"
> >
<slot name="content"></slot> <slot name="content"></slot>
</LayoutContent> </LayoutContent>
<LayoutFooter <LayoutFooter
v-if="footerVisible" v-if="footerEnable"
:fixed="footerFixed" :fixed="footerFixed"
:height="footerHeight" :height="footerHeight"
:show="!fullContent" :show="!fullContent"
@@ -566,8 +566,8 @@ function handleOpenMenu() {
</div> </div>
<div <div
v-if="maskVisible" v-if="maskVisible"
class="fixed left-0 top-0 h-full w-full bg-[rgb(0_0_0_/_40%)] transition-[background-color] duration-200"
:style="maskStyle" :style="maskStyle"
class="fixed left-0 top-0 h-full w-full bg-[rgb(0_0_0_/_40%)] transition-[background-color] duration-200"
@click="handleClickMask" @click="handleClickMask"
></div> ></div>
</div> </div>

View File

@@ -334,7 +334,7 @@ function removeMenuItem(item: MenuItemRegistered) {
<template v-for="item in getSlot.slotDefault" :key="item.key"> <template v-for="item in getSlot.slotDefault" :key="item.key">
<component :is="item" /> <component :is="item" />
</template> </template>
<SubMenu path="sub-menu-more" is-sub-menu-more> <SubMenu is-sub-menu-more path="sub-menu-more">
<template #title> <template #title>
<IcRoundMoreHoriz /> <IcRoundMoreHoriz />
</template> </template>

View File

@@ -214,11 +214,11 @@ onBeforeUnmount(() => {
<template #trigger> <template #trigger>
<SubMenuContent <SubMenuContent
:class="is('active', active)" :class="is('active', active)"
:icon="icon"
:is-menu-more="isSubMenuMore"
:is-top-level-menu-submenu="isTopLevelMenuSubmenu" :is-top-level-menu-submenu="isTopLevelMenuSubmenu"
:level="currentLevel" :level="currentLevel"
:path="path" :path="path"
:icon="icon"
:is-menu-more="isSubMenuMore"
@click.stop="handleClick" @click.stop="handleClick"
> >
<template #title> <template #title>
@@ -244,12 +244,12 @@ onBeforeUnmount(() => {
<template v-else> <template v-else>
<SubMenuContent <SubMenuContent
:class="is('active', active)"
:icon="icon"
:is-menu-more="isSubMenuMore"
:is-top-level-menu-submenu="isTopLevelMenuSubmenu" :is-top-level-menu-submenu="isTopLevelMenuSubmenu"
:level="currentLevel" :level="currentLevel"
:path="path" :path="path"
:icon="icon"
:is-menu-more="isSubMenuMore"
:class="is('active', active)"
@click.stop="handleClick" @click.stop="handleClick"
> >
<slot name="content"></slot> <slot name="content"></slot>

View File

@@ -37,19 +37,19 @@ const hasChildren = computed(() => {
<MenuItem <MenuItem
v-if="!hasChildren" v-if="!hasChildren"
:key="menu.path" :key="menu.path"
:path="menu.path"
:icon="menu.icon"
:badge="menu.badge" :badge="menu.badge"
:badge-type="menu.badgeType" :badge-type="menu.badgeType"
:badge-variants="menu.badgeVariants" :badge-variants="menu.badgeVariants"
:icon="menu.icon"
:path="menu.path"
> >
<template #title>{{ menu.name }}</template> <template #title>{{ menu.name }}</template>
</MenuItem> </MenuItem>
<SubMenuComp <SubMenuComp
v-else v-else
:key="`${menu.path}_sub`" :key="`${menu.path}_sub`"
:path="menu.path"
:icon="menu.icon" :icon="menu.icon"
:path="menu.path"
> >
<template #content> <template #content>
<VbenMenuBadge <VbenMenuBadge

View File

@@ -41,8 +41,8 @@ const text = computed(() => {
</Avatar> </Avatar>
<span <span
v-if="dot" v-if="dot"
class="border-background absolute bottom-0 right-0 size-3 rounded-full border-2"
:class="dotClass" :class="dotClass"
class="border-background absolute bottom-0 right-0 size-3 rounded-full border-2"
> >
</span> </span>
</div> </div>

View File

@@ -34,8 +34,8 @@ function handleClick(path?: string) {
<span class="flex-center h-full"> <span class="flex-center h-full">
<VbenIcon <VbenIcon
v-if="item.icon && showIcon" v-if="item.icon && showIcon"
class="mr-1 size-5 flex-shrink-0"
:icon="item.icon" :icon="item.icon"
class="mr-1 size-5 flex-shrink-0"
/> />
<span <span
:class="{ :class="{

View File

@@ -53,8 +53,8 @@ function handleClick(path?: string) {
<DropdownMenuTrigger class="flex items-center gap-1"> <DropdownMenuTrigger class="flex items-center gap-1">
<VbenIcon <VbenIcon
v-if="item.icon && showIcon" v-if="item.icon && showIcon"
class="size-5"
:icon="item.icon" :icon="item.icon"
class="size-5"
/> />
{{ item.title }} {{ item.title }}
<IcRoundKeyboardArrowDown class="size-5" /> <IcRoundKeyboardArrowDown class="size-5" />
@@ -79,9 +79,9 @@ function handleClick(path?: string) {
<div class="flex-center"> <div class="flex-center">
<VbenIcon <VbenIcon
v-if="item.icon && showIcon" v-if="item.icon && showIcon"
class="mr-1 size-4"
:class="{ 'size-5': item.isHome }" :class="{ 'size-5': item.isHome }"
:icon="item.icon" :icon="item.icon"
class="mr-1 size-4"
/> />
{{ item.title }} {{ item.title }}
</div> </div>
@@ -90,9 +90,9 @@ function handleClick(path?: string) {
<div class="flex-center"> <div class="flex-center">
<VbenIcon <VbenIcon
v-if="item.icon && showIcon" v-if="item.icon && showIcon"
class="mr-1 size-4"
:class="{ 'size-5': item.isHome }" :class="{ 'size-5': item.isHome }"
:icon="item.icon" :icon="item.icon"
class="mr-1 size-4"
/> />
{{ item.title }} {{ item.title }}
</div> </div>

View File

@@ -72,10 +72,10 @@ function handleClick(menu: IContextMenuItem) {
> >
<template v-for="menu in menusView" :key="menu.key"> <template v-for="menu in menusView" :key="menu.key">
<ContextMenuItem <ContextMenuItem
:inset="menu.inset || !menu.icon"
:disabled="menu.disabled"
class="cursor-pointer"
:class="itemClass" :class="itemClass"
:disabled="menu.disabled"
:inset="menu.inset || !menu.icon"
class="cursor-pointer"
@click="handleClick(menu)" @click="handleClick(menu)"
> >
<component <component

View File

@@ -22,24 +22,24 @@ function handleItemClick(value: string) {
</script> </script>
<template> <template>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger class="flex items-center gap-1" as-child> <DropdownMenuTrigger as-child class="flex items-center gap-1">
<slot></slot> <slot></slot>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="start"> <DropdownMenuContent align="start">
<DropdownMenuGroup> <DropdownMenuGroup>
<template v-for="menu in menus" :key="menu.key"> <template v-for="menu in menus" :key="menu.key">
<DropdownMenuItem <DropdownMenuItem
class="data-[state=checked]:bg-accent data-[state=checked]:text-accent-foreground text-foreground/80 mb-1 cursor-pointer"
:class=" :class="
menu.key === modelValue ? 'bg-accent text-accent-foreground' : '' menu.key === modelValue ? 'bg-accent text-accent-foreground' : ''
" "
class="data-[state=checked]:bg-accent data-[state=checked]:text-accent-foreground text-foreground/80 mb-1 cursor-pointer"
@click="handleItemClick(menu.key)" @click="handleItemClick(menu.key)"
> >
<component :is="menu.icon" v-if="menu.icon" class="mr-2 size-4" /> <component :is="menu.icon" v-if="menu.icon" class="mr-2 size-4" />
<span <span
v-if="!menu.icon" v-if="!menu.icon"
class="mr-2 size-1.5 rounded-full"
:class="menu.key === modelValue ? 'bg-foreground' : ''" :class="menu.key === modelValue ? 'bg-foreground' : ''"
class="mr-2 size-1.5 rounded-full"
></span> ></span>
{{ menu.text }} {{ menu.text }}
</DropdownMenuItem> </DropdownMenuItem>

View File

@@ -16,18 +16,18 @@ const handleMenuItemClick = (_item) => {
<template> <template>
<div class="fixed bottom-5 right-5 flex flex-col-reverse items-center gap-2"> <div class="fixed bottom-5 right-5 flex flex-col-reverse items-center gap-2">
<button <button
class="flex h-12 w-12 items-center justify-center rounded-full bg-blue-500 text-xl text-white transition-transform duration-300"
:class="{ 'rotate-45': isMenuOpen }" :class="{ 'rotate-45': isMenuOpen }"
class="flex h-12 w-12 items-center justify-center rounded-full bg-blue-500 text-xl text-white transition-transform duration-300"
@click="toggleMenu" @click="toggleMenu"
> >
</button> </button>
<div <div
class="absolute bottom-16 right-0 flex flex-col-reverse gap-2 transition-all duration-300"
:class="{ :class="{
'visible translate-y-0 opacity-100': isMenuOpen, 'visible translate-y-0 opacity-100': isMenuOpen,
'invisible translate-y-2 opacity-0': !isMenuOpen, 'invisible translate-y-2 opacity-0': !isMenuOpen,
}" }"
class="absolute bottom-16 right-0 flex flex-col-reverse gap-2 transition-all duration-300"
> >
<button <button
v-for="(item, index) in menuItems" v-for="(item, index) in menuItems"

View File

@@ -54,11 +54,11 @@ function checkPasswordStrength(password: string) {
class="dark:bg-input-background bg-heavy relative mr-1 h-1.5 w-1/5 rounded-sm last:mr-0" class="dark:bg-input-background bg-heavy relative mr-1 h-1.5 w-1/5 rounded-sm last:mr-0"
> >
<span <span
class="absolute left-0 h-full w-0 rounded-sm transition-all duration-500"
:style="{ :style="{
backgroundColor: currentColor, backgroundColor: currentColor,
width: currentStrength >= index ? '100%' : '', width: currentStrength >= index ? '100%' : '',
}" }"
class="absolute left-0 h-full w-0 rounded-sm transition-all duration-500"
></span> ></span>
</div> </div>
</template> </template>

View File

@@ -32,8 +32,8 @@ const inputClass = computed(() => {
:id="name" :id="name"
v-model="modelValue" v-model="modelValue"
:class="[props.class, inputClass]" :class="[props.class, inputClass]"
class="border-input bg-input-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring focus:border-primary flex h-10 w-full rounded-md border p-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
autocomplete="off" autocomplete="off"
class="border-input bg-input-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring focus:border-primary flex h-10 w-full rounded-md border p-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
required required
type="text" type="text"
v-bind="$attrs" v-bind="$attrs"

View File

@@ -51,16 +51,16 @@ const logoClass = computed(() => {
</script> </script>
<template> <template>
<div class="group flex h-full items-center text-lg" :class="logoClass"> <div :class="logoClass" class="group flex h-full items-center text-lg">
<a <a
:class="$attrs.class"
:href="href" :href="href"
class="flex h-full items-center gap-2 overflow-hidden px-3 font-semibold leading-normal transition-all duration-500" class="flex h-full items-center gap-2 overflow-hidden px-3 font-semibold leading-normal transition-all duration-500"
:class="$attrs.class"
> >
<img <img
v-if="src" v-if="src"
:src="src"
:alt="alt" :alt="alt"
:src="src"
:width="logoSize" :width="logoSize"
class="relative rounded-none bg-transparent" class="relative rounded-none bg-transparent"
/> />

View File

@@ -14,15 +14,15 @@ withDefaults(defineProps<Props>(), {
<template> <template>
<span class="relative mr-1 flex size-1.5"> <span class="relative mr-1 flex size-1.5">
<span <span
class="absolute inline-flex h-full w-full animate-ping rounded-full opacity-75"
:class="dotClass" :class="dotClass"
:style="dotStyle" :style="dotStyle"
class="absolute inline-flex h-full w-full animate-ping rounded-full opacity-75"
> >
</span> </span>
<span <span
class="relative inline-flex size-1.5 rounded-full"
:class="dotClass" :class="dotClass"
:style="dotStyle" :style="dotStyle"
class="relative inline-flex size-1.5 rounded-full"
></span> ></span>
</span> </span>
</template> </template>

View File

@@ -43,7 +43,7 @@ const badgeStyle = computed(() => {
}); });
</script> </script>
<template> <template>
<span v-if="isDot || badge" class="absolute right-5" :class="$attrs.class"> <span v-if="isDot || badge" :class="$attrs.class" class="absolute right-5">
<BadgeDot v-if="isDot" :dot-class="badgeClass" :dot-style="badgeStyle" /> <BadgeDot v-if="isDot" :dot-class="badgeClass" :dot-style="badgeStyle" />
<div <div
v-else v-else

View File

@@ -56,10 +56,10 @@ function handleComplete(e: string[]) {
<PinInput <PinInput
:id="name" :id="name"
v-model="inputValue" v-model="inputValue"
:class="inputClass"
class="flex justify-between"
otp otp
placeholder="○" placeholder="○"
class="flex justify-between"
:class="inputClass"
type="number" type="number"
@complete="handleComplete" @complete="handleComplete"
> >
@@ -71,10 +71,10 @@ function handleComplete(e: string[]) {
/> />
</PinInputGroup> </PinInputGroup>
<VbenButton <VbenButton
:loading="btnLoading"
class="w-[300px] xl:w-full" class="w-[300px] xl:w-full"
size="lg" size="lg"
variant="outline" variant="outline"
:loading="btnLoading"
@click="handleSendCode" @click="handleSendCode"
> >
{{ btnText }} {{ btnText }}

View File

@@ -7,7 +7,7 @@ const props = defineProps<{
</script> </script>
<template> <template>
<nav aria-label="breadcrumb" role="navigation" :class="props.class"> <nav :class="props.class" aria-label="breadcrumb" role="navigation">
<slot></slot> <slot></slot>
</nav> </nav>
</template> </template>

View File

@@ -12,9 +12,9 @@ const props = defineProps<{
<template> <template>
<span <span
role="presentation"
aria-hidden="true"
:class="cn('flex h-9 w-9 items-center justify-center', props.class)" :class="cn('flex h-9 w-9 items-center justify-center', props.class)"
aria-hidden="true"
role="presentation"
> >
<slot> <slot>
<DotsHorizontalIcon class="h-4 w-4" /> <DotsHorizontalIcon class="h-4 w-4" />

View File

@@ -10,10 +10,10 @@ const props = defineProps<{
<template> <template>
<span <span
role="link"
aria-disabled="true"
aria-current="page"
:class="cn('text-foreground font-normal', props.class)" :class="cn('text-foreground font-normal', props.class)"
aria-current="page"
aria-disabled="true"
role="link"
> >
<slot></slot> <slot></slot>
</span> </span>

View File

@@ -12,9 +12,9 @@ const props = defineProps<{
<template> <template>
<li <li
role="presentation"
aria-hidden="true"
:class="cn('[&>svg]:size-3.5', props.class)" :class="cn('[&>svg]:size-3.5', props.class)"
aria-hidden="true"
role="presentation"
> >
<slot> <slot>
<ChevronRightIcon /> <ChevronRightIcon />

View File

@@ -37,8 +37,8 @@ const delegatedProps = computed(() => {
:class="cn('relative overflow-hidden', props.class)" :class="cn('relative overflow-hidden', props.class)"
> >
<ScrollAreaViewport <ScrollAreaViewport
class="h-full w-full rounded-[inherit]"
as-child as-child
class="h-full w-full rounded-[inherit]"
@scroll="onScroll" @scroll="onScroll"
> >
<slot></slot> <slot></slot>

View File

@@ -12,10 +12,10 @@ const { b, e } = useNamespace('chrome-tab-background');
<div :class="b()"> <div :class="b()">
<div :class="e('divider')"></div> <div :class="e('divider')"></div>
<div :class="e('content')"></div> <div :class="e('content')"></div>
<svg width="10" height="10" :class="e('before')"> <svg :class="e('before')" height="10" width="10">
<path d="M 0 10 A 10 10 0 0 0 10 0 L 10 10 Z" /> <path d="M 0 10 A 10 10 0 0 0 10 0 L 10 10 Z" />
</svg> </svg>
<svg width="10" height="10" :class="e('after')"> <svg :class="e('after')" height="10" width="10">
<path d="M 0 0 A 10 10 0 0 0 10 10 L 0 10 Z" /> <path d="M 0 0 A 10 10 0 0 0 10 10 L 0 10 Z" />
</svg> </svg>
</div> </div>

View File

@@ -39,7 +39,7 @@ function handleUnPushPin() {
<template> <template>
<div :class="[b()]"> <div :class="[b()]">
<VbenContextMenu :menus="menus" :handler-data="tab" item-class="pr-4"> <VbenContextMenu :handler-data="tab" :menus="menus" item-class="pr-4">
<div class="h-full"> <div class="h-full">
<TabBackground /> <TabBackground />
<div :class="e('content')" :title="title"> <div :class="e('content')" :title="title">

View File

@@ -89,18 +89,18 @@ function handleUnPushPin(tab: TabItem) {
<Tab <Tab
v-for="(tab, i) in tabsView" v-for="(tab, i) in tabsView"
:key="tab.key" :key="tab.key"
:menus="menus"
:tab="tab"
:icon="tab.icon"
:title="tab.title"
:show-icon="showIcon"
:affix-tab="tab.affixTab" :affix-tab="tab.affixTab"
:only-one="tabsView.length <= 1"
:class="[e('tab'), is('active', tab.key === active)]" :class="[e('tab'), is('active', tab.key === active)]"
:icon="tab.icon"
:menus="menus"
:only-one="tabsView.length <= 1"
:show-icon="showIcon"
:style="{ :style="{
width: `${tabWidth}px`, width: `${tabWidth}px`,
left: `${(tabWidth - gap * 2) * i}px`, left: `${(tabWidth - gap * 2) * i}px`,
}" }"
:tab="tab"
:title="tab.title"
@click="active = tab.key" @click="active = tab.key"
@close="() => handleClose(tab.key)" @close="() => handleClose(tab.key)"
@un-push-pin="() => handleUnPushPin(tab)" @un-push-pin="() => handleUnPushPin(tab)"

View File

@@ -125,26 +125,26 @@ onBeforeUnmount(() => {
</Title> </Title>
<VbenInput <VbenInput
v-model="formState.phoneNumber" v-model="formState.phoneNumber"
:status="phoneNumberStatus" :autofocus="true"
:error-tip="$t('authentication.mobile-tip')" :error-tip="$t('authentication.mobile-tip')"
:label="$t('authentication.mobile')" :label="$t('authentication.mobile')"
:placeholder="$t('authentication.mobile')"
:status="phoneNumberStatus"
name="phoneNumber" name="phoneNumber"
type="number" type="number"
:placeholder="$t('authentication.mobile')"
:autofocus="true"
@keyup.enter="handleSubmit" @keyup.enter="handleSubmit"
/> />
<VbenPinInput <VbenPinInput
v-model="formState.code" v-model="formState.code"
:handle-send-code="handleSendCode" :btn-loading="btnLoading"
:status="codeStatus" :btn-text="btnText"
:code-length="4" :code-length="4"
:error-tip="$t('authentication.code-tip')" :error-tip="$t('authentication.code-tip')"
:handle-send-code="handleSendCode"
:label="$t('authentication.code')" :label="$t('authentication.code')"
name="password"
:placeholder="$t('authentication.code')" :placeholder="$t('authentication.code')"
:btn-text="btnText" :status="codeStatus"
:btn-loading="btnLoading" name="password"
@keyup.enter="handleSubmit" @keyup.enter="handleSubmit"
/> />
<VbenButton :loading="loading" class="mt-2 w-full" @click="handleSubmit"> <VbenButton :loading="loading" class="mt-2 w-full" @click="handleSubmit">

View File

@@ -65,11 +65,11 @@ function goLogin() {
<div class="mb-6"> <div class="mb-6">
<VbenInput <VbenInput
v-model="formState.email" v-model="formState.email"
:status="emailStatus"
:error-tip="$t('authentication.email-tip')" :error-tip="$t('authentication.email-tip')"
:label="$t('authentication.email')" :label="$t('authentication.email')"
name="email" :status="emailStatus"
autofocus autofocus
name="email"
placeholder="example@example.com" placeholder="example@example.com"
type="text" type="text"
/> />

View File

@@ -160,22 +160,22 @@ function handleGo(path: string) {
<VbenInput <VbenInput
v-model="formState.username" v-model="formState.username"
:status="usernameStatus" :autofocus="false"
:error-tip="$t('authentication.username-tip')" :error-tip="$t('authentication.username-tip')"
:label="$t('authentication.username')" :label="$t('authentication.username')"
name="username"
:placeholder="usernamePlaceholder || $t('authentication.username')" :placeholder="usernamePlaceholder || $t('authentication.username')"
type="text" :status="usernameStatus"
name="username"
required required
:autofocus="false" type="text"
/> />
<VbenInputPassword <VbenInputPassword
v-model="formState.password" v-model="formState.password"
:status="passwordStatus"
:error-tip="$t('authentication.password-tip')" :error-tip="$t('authentication.password-tip')"
:label="$t('authentication.password')" :label="$t('authentication.password')"
name="password"
:placeholder="passwordPlaceholder || $t('authentication.password')" :placeholder="passwordPlaceholder || $t('authentication.password')"
:status="passwordStatus"
name="password"
required required
type="password" type="password"
/> />
@@ -205,16 +205,16 @@ function handleGo(path: string) {
<div class="mb-2 mt-4 flex items-center justify-between"> <div class="mb-2 mt-4 flex items-center justify-between">
<VbenButton <VbenButton
v-if="showCodeLogin" v-if="showCodeLogin"
variant="outline"
class="w-1/2" class="w-1/2"
variant="outline"
@click="handleGo(codeLoginPath)" @click="handleGo(codeLoginPath)"
> >
{{ $t('authentication.mobile-login') }} {{ $t('authentication.mobile-login') }}
</VbenButton> </VbenButton>
<VbenButton <VbenButton
v-if="showQrcodeLogin" v-if="showQrcodeLogin"
variant="outline"
class="ml-4 w-1/2" class="ml-4 w-1/2"
variant="outline"
@click="handleGo(qrCodeLoginPath)" @click="handleGo(qrCodeLoginPath)"
> >
{{ $t('authentication.qrcode-login') }} {{ $t('authentication.qrcode-login') }}

View File

@@ -90,24 +90,24 @@ function goLogin() {
</Title> </Title>
<VbenInput <VbenInput
v-model="formState.username" v-model="formState.username"
:status="usernameStatus"
:error-tip="$t('authentication.username-tip')" :error-tip="$t('authentication.username-tip')"
:label="$t('authentication.username')" :label="$t('authentication.username')"
name="username"
:placeholder="$t('authentication.username')" :placeholder="$t('authentication.username')"
:status="usernameStatus"
name="username"
type="text" type="text"
/> />
<!-- Use 8 or more characters with a mix of letters, numbers & symbols. --> <!-- Use 8 or more characters with a mix of letters, numbers & symbols. -->
<VbenInputPassword <VbenInputPassword
v-model="formState.password" v-model="formState.password"
:status="passwordStatus"
:error-tip="$t('authentication.password-tip')" :error-tip="$t('authentication.password-tip')"
:label="$t('authentication.password')" :label="$t('authentication.password')"
name="password" :password-strength="true"
:placeholder="$t('authentication.password')" :placeholder="$t('authentication.password')"
:status="passwordStatus"
name="password"
required required
type="password" type="password"
:password-strength="true"
> >
<template #strengthText> <template #strengthText>
{{ $t('authentication.password-strength') }} {{ $t('authentication.password-strength') }}
@@ -116,11 +116,11 @@ function goLogin() {
<VbenInputPassword <VbenInputPassword
v-model="formState.comfirmPassword" v-model="formState.comfirmPassword"
:status="comfirmPasswordStatus"
:error-tip="$t('authentication.comfirm-password-tip')" :error-tip="$t('authentication.comfirm-password-tip')"
:label="$t('authentication.comfirm-password')" :label="$t('authentication.comfirm-password')"
name="comfirmPassword"
:placeholder="$t('authentication.comfirm-password')" :placeholder="$t('authentication.comfirm-password')"
:status="comfirmPasswordStatus"
name="comfirmPassword"
required required
type="password" type="password"
/> />

View File

@@ -31,13 +31,13 @@ function handleUpdate(value: string) {
@click="handleUpdate(color)" @click="handleUpdate(color)"
> >
<div <div
class="relative h-3.5 w-3.5 rounded-[2px] before:absolute before:left-0.5 before:top-0.5 before:h-2.5 before:w-2.5 before:rounded-[2px] before:border before:border-gray-900 before:opacity-0 before:transition-all before:duration-150 before:content-[''] hover:scale-110"
:class="[ :class="[
preferences.theme.colorPrimary === color preferences.theme.colorPrimary === color
? `before:opacity-100` ? `before:opacity-100`
: '', : '',
]" ]"
:style="{ backgroundColor: color }" :style="{ backgroundColor: color }"
class="relative h-3.5 w-3.5 rounded-[2px] before:absolute before:left-0.5 before:top-0.5 before:h-2.5 before:w-2.5 before:rounded-[2px] before:border before:border-gray-900 before:opacity-0 before:transition-all before:duration-150 before:content-[''] hover:scale-110"
></div> ></div>
</VbenIconButton> </VbenIconButton>
</template> </template>

View File

@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AuthPageLayoutType } from '@vben-core/preferences';
import type { VbenDropdownMenuItem } from '@vben-core/shadcn-ui'; import type { VbenDropdownMenuItem } from '@vben-core/shadcn-ui';
import { computed } from 'vue'; import { computed } from 'vue';
@@ -6,7 +7,6 @@ import { computed } from 'vue';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { MdiDockBottom, MdiDockLeft, MdiDockRight } from '@vben-core/iconify'; import { MdiDockBottom, MdiDockLeft, MdiDockRight } from '@vben-core/iconify';
import { import {
type AuthPageLayoutType,
preferences, preferences,
updatePreferences, updatePreferences,
usePreferences, usePreferences,

View File

@@ -1,24 +1,24 @@
<template> <template>
<svg <svg
xmlns="http://www.w3.org/2000/svg"
width="586"
height="659.29778" height="659.29778"
viewBox="0 0 586 659.29778" viewBox="0 0 586 659.29778"
width="586"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
> >
<circle cx="332.47856" cy="254" r="254.00001" fill="#f2f2f2" /> <circle cx="332.47856" cy="254" fill="#f2f2f2" r="254.00001" />
<path <path
d="M498.46363,113.58835H33.17063c-.99774-.02133-1.78931-.84746-1.76797-1.84521,.02069-.96771,.80026-1.74727,1.76797-1.76796H498.46363c.99774,.02133,1.78931,.84746,1.76794,1.84521-.02069,.96771-.80023,1.74727-1.76794,1.76796Z" d="M498.46363,113.58835H33.17063c-.99774-.02133-1.78931-.84746-1.76797-1.84521,.02069-.96771,.80026-1.74727,1.76797-1.76796H498.46363c.99774,.02133,1.78931,.84746,1.76794,1.84521-.02069,.96771-.80023,1.74727-1.76794,1.76796Z"
fill="#cacaca" fill="#cacaca"
/> />
<rect <rect
x="193.77441" fill="#fff"
y="174.47256"
width="163.61147"
height="34.98639" height="34.98639"
rx="17.49318" rx="17.49318"
ry="17.49318" ry="17.49318"
fill="#fff" width="163.61147"
x="193.77441"
y="174.47256"
/> />
<path <path
d="M128.17493,244.44534H422.98542c9.66122,0,17.49316,7.83197,17.49316,17.49319h0c0,9.66122-7.83194,17.49319-17.49316,17.49319H128.17493c-9.66122,0-17.49318-7.83197-17.49318-17.49319h0c0-9.66122,7.83196-17.49319,17.49318-17.49319Z" d="M128.17493,244.44534H422.98542c9.66122,0,17.49316,7.83197,17.49316,17.49319h0c0,9.66122-7.83194,17.49319-17.49316,17.49319H128.17493c-9.66122,0-17.49318-7.83197-17.49318-17.49319h0c0-9.66122,7.83196-17.49319,17.49318-17.49319Z"
@@ -33,16 +33,16 @@
fill="#f2f2f2" fill="#f2f2f2"
/> />
<polygon <polygon
points="171.30016 646.86102 182.10017 646.85999 187.23916 605.198 171.29716 605.19897 171.30016 646.86102"
fill="#a0616a" fill="#a0616a"
points="171.30016 646.86102 182.10017 646.85999 187.23916 605.198 171.29716 605.19897 171.30016 646.86102"
/> />
<path <path
d="M170.9192,658.12816l33.21436-.00122v-.41998c-.00049-7.13965-5.78833-12.92737-12.92798-12.92773h-.00079l-6.06702-4.60278-11.3197,4.60345-2.89941,.00012,.00055,13.34814Z" d="M170.9192,658.12816l33.21436-.00122v-.41998c-.00049-7.13965-5.78833-12.92737-12.92798-12.92773h-.00079l-6.06702-4.60278-11.3197,4.60345-2.89941,.00012,.00055,13.34814Z"
fill="#2f2e41" fill="#2f2e41"
/> />
<polygon <polygon
points="84.74116 616.94501 93.38016 623.42603 122.49316 593.185 109.74116 583.61902 84.74116 616.94501"
fill="#a0616a" fill="#a0616a"
points="84.74116 616.94501 93.38016 623.42603 122.49316 593.185 109.74116 583.61902 84.74116 616.94501"
/> />
<path <path
d="M77.67448,625.72966l26.569,19.93188,.25208-.336c4.2843-5.71136,3.12799-13.81433-2.58279-18.09937l-.00064-.00049-2.09079-7.32275-11.81735-3.11102-2.31931-1.73993-8.01019,10.67767Z" d="M77.67448,625.72966l26.569,19.93188,.25208-.336c4.2843-5.71136,3.12799-13.81433-2.58279-18.09937l-.00064-.00049-2.09079-7.32275-11.81735-3.11102-2.31931-1.73993-8.01019,10.67767Z"
@@ -64,7 +64,7 @@
d="M157.62488,302.62425l-5.26666-.55807c-4.86633-.50473-9.64093,1.57941-12.57947,5.491-1.12549,1.48346-1.9339,3.18253-2.37491,4.99164l-.00317,.01447c-1.32108,5.44534,.75095,11.15201,5.25803,14.48117l18.19031,13.41101c12.76544,17.24899,36.75653,28.69272,64.89832,37.98978l43.74274-27.16666-15.47186-18.73843-30.00336,16.0798-44.59833-34.52374-.0257-.02075-16.97424-10.936-4.79169-.5152Z" d="M157.62488,302.62425l-5.26666-.55807c-4.86633-.50473-9.64093,1.57941-12.57947,5.491-1.12549,1.48346-1.9339,3.18253-2.37491,4.99164l-.00317,.01447c-1.32108,5.44534,.75095,11.15201,5.25803,14.48117l18.19031,13.41101c12.76544,17.24899,36.75653,28.69272,64.89832,37.98978l43.74274-27.16666-15.47186-18.73843-30.00336,16.0798-44.59833-34.52374-.0257-.02075-16.97424-10.936-4.79169-.5152Z"
fill="#3f3d56" fill="#3f3d56"
/> />
<circle cx="167.29993" cy="248.60526" r="24.9798" fill="#a0616a" /> <circle cx="167.29993" cy="248.60526" fill="#a0616a" r="24.9798" />
<path <path
d="M167.8769,273.59047c-.20135,.00662-.4032,.01108-.6048,.01657-.0863,.22388-.17938,.44583-.2868,.66357l.8916-.68015Z" d="M167.8769,273.59047c-.20135,.00662-.4032,.01108-.6048,.01657-.0863,.22388-.17938,.44583-.2868,.66357l.8916-.68015Z"
fill="#2f2e41" fill="#2f2e41"
@@ -80,9 +80,9 @@
<circle <circle
cx="281.3585" cx="281.3585"
cy="285.71051" cy="285.71051"
fill="hsl(var(--color-primary))"
r="51.12006" r="51.12006"
transform="translate(-26.58509 542.54478) rotate(-85.26884)" transform="translate(-26.58509 542.54478) rotate(-85.26884)"
fill="hsl(var(--color-primary))"
/> />
<path <path
d="M294.78675,264.41051l-13.42828,13.42828-13.42828-13.42828c-2.17371-2.17374-5.69806-2.17374-7.87177,0s-2.17371,5.69803,0,7.87177l13.42828,13.42828-13.42828,13.42828c-2.17169,2.17575-2.1684,5.70007,.00739,7.87177,2.17285,2.16879,5.69153,2.16879,7.86438-.00003l13.42828-13.42828,13.42828,13.42828c2.17578,2.17169,5.70007,2.1684,7.87177-.00735,2.16882-2.17288,2.16882-5.6915,0-7.86438l-13.42828-13.42828,13.42828-13.42828c2.17371-2.17374,2.17371-5.69803,0-7.87177s-5.69806-2.17374-7.87177,0h0Z" d="M294.78675,264.41051l-13.42828,13.42828-13.42828-13.42828c-2.17371-2.17374-5.69806-2.17374-7.87177,0s-2.17371,5.69803,0,7.87177l13.42828,13.42828-13.42828,13.42828c-2.17169,2.17575-2.1684,5.70007,.00739,7.87177,2.17285,2.16879,5.69153,2.16879,7.86438-.00003l13.42828-13.42828,13.42828,13.42828c2.17578,2.17169,5.70007,2.1684,7.87177-.00735,2.16882-2.17288,2.16882-5.6915,0-7.86438l-13.42828-13.42828,13.42828-13.42828c2.17371-2.17374,2.17371-5.69803,0-7.87177s-5.69806-2.17374-7.87177,0h0Z"
@@ -104,23 +104,23 @@
<ellipse <ellipse
cx="56.77685" cx="56.77685"
cy="82.05834" cy="82.05834"
fill="#3f3d56"
rx="8.45661" rx="8.45661"
ry="8.64507" ry="8.64507"
fill="#3f3d56"
/> />
<ellipse <ellipse
cx="85.9906" cx="85.9906"
cy="82.05834" cy="82.05834"
fill="#3f3d56"
rx="8.45661" rx="8.45661"
ry="8.64507" ry="8.64507"
fill="#3f3d56"
/> />
<ellipse <ellipse
cx="115.20435" cx="115.20435"
cy="82.05834" cy="82.05834"
fill="#3f3d56"
rx="8.45661" rx="8.45661"
ry="8.64507" ry="8.64507"
fill="#3f3d56"
/> />
<path <path
d="M148.51577,88.89113c-.25977,0-.51904-.10059-.71484-.30078l-5.70605-5.83301c-.38037-.38867-.38037-1.00977,0-1.39844l5.70605-5.83252c.38721-.39453,1.021-.40088,1.41406-.01562,.39502,.38623,.40186,1.01953,.01562,1.41406l-5.02197,5.1333,5.02197,5.13379c.38623,.39453,.37939,1.02783-.01562,1.41406-.19434,.19043-.44678,.28516-.69922,.28516Z" d="M148.51577,88.89113c-.25977,0-.51904-.10059-.71484-.30078l-5.70605-5.83301c-.38037-.38867-.38037-1.00977,0-1.39844l5.70605-5.83252c.38721-.39453,1.021-.40088,1.41406-.01562,.39502,.38623,.40186,1.01953,.01562,1.41406l-5.02197,5.1333,5.02197,5.13379c.38623,.39453,.37939,1.02783-.01562,1.41406-.19434,.19043-.44678,.28516-.69922,.28516Z"

View File

@@ -1,215 +1,215 @@
<template> <template>
<svg <svg
xmlns="http://www.w3.org/2000/svg"
width="1119"
height="699" height="699"
viewBox="0 0 1119 699" viewBox="0 0 1119 699"
width="1119"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
> >
<title>server down</title> <title>server down</title>
<circle cx="292.60911" cy="213" r="213" fill="#f2f2f2" /> <circle cx="292.60911" cy="213" fill="#f2f2f2" r="213" />
<path <path
d="M31.39089,151.64237c0,77.49789,48.6181,140.20819,108.70073,140.20819" d="M31.39089,151.64237c0,77.49789,48.6181,140.20819,108.70073,140.20819"
transform="translate(-31.39089 -100.5)"
fill="#2f2e41" fill="#2f2e41"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M140.09162,291.85056c0-78.36865,54.255-141.78356,121.30372-141.78356" d="M140.09162,291.85056c0-78.36865,54.255-141.78356,121.30372-141.78356"
transform="translate(-31.39089 -100.5)"
fill="hsl(var(--color-primary))" fill="hsl(var(--color-primary))"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M70.77521,158.66768c0,73.61476,31.00285,133.18288,69.31641,133.18288" d="M70.77521,158.66768c0,73.61476,31.00285,133.18288,69.31641,133.18288"
transform="translate(-31.39089 -100.5)"
fill="hsl(var(--color-primary))" fill="hsl(var(--color-primary))"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M140.09162,291.85056c0-100.13772,62.7103-181.16788,140.20819-181.16788" d="M140.09162,291.85056c0-100.13772,62.7103-181.16788,140.20819-181.16788"
transform="translate(-31.39089 -100.5)"
fill="#2f2e41" fill="#2f2e41"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M117.22379,292.83905s15.41555-.47479,20.06141-3.783,23.713-7.2585,24.86553-1.95278,23.16671,26.38821,5.76263,26.5286-40.43935-2.711-45.07627-5.53549S117.22379,292.83905,117.22379,292.83905Z" d="M117.22379,292.83905s15.41555-.47479,20.06141-3.783,23.713-7.2585,24.86553-1.95278,23.16671,26.38821,5.76263,26.5286-40.43935-2.711-45.07627-5.53549S117.22379,292.83905,117.22379,292.83905Z"
transform="translate(-31.39089 -100.5)"
fill="#a8a8a8" fill="#a8a8a8"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M168.224,311.78489c-17.40408.14042-40.43933-2.71094-45.07626-5.53548-3.53126-2.151-4.93843-9.86945-5.40926-13.43043-.32607.014-.51463.02-.51463.02s.97638,12.43276,5.61331,15.2573,27.67217,5.67589,45.07626,5.53547c5.02386-.04052,6.7592-1.82793,6.66391-4.47526C173.87935,310.756,171.96329,311.75474,168.224,311.78489Z" d="M168.224,311.78489c-17.40408.14042-40.43933-2.71094-45.07626-5.53548-3.53126-2.151-4.93843-9.86945-5.40926-13.43043-.32607.014-.51463.02-.51463.02s.97638,12.43276,5.61331,15.2573,27.67217,5.67589,45.07626,5.53547c5.02386-.04052,6.7592-1.82793,6.66391-4.47526C173.87935,310.756,171.96329,311.75474,168.224,311.78489Z"
transform="translate(-31.39089 -100.5)"
opacity="0.2" opacity="0.2"
transform="translate(-31.39089 -100.5)"
/> />
<ellipse cx="198.60911" cy="424.5" rx="187" ry="25.43993" fill="#3f3d56" /> <ellipse cx="198.60911" cy="424.5" fill="#3f3d56" rx="187" ry="25.43993" />
<ellipse cx="198.60911" cy="424.5" rx="157" ry="21.35866" opacity="0.1" /> <ellipse cx="198.60911" cy="424.5" opacity="0.1" rx="157" ry="21.35866" />
<ellipse cx="836.60911" cy="660.5" rx="283" ry="38.5" fill="#3f3d56" /> <ellipse cx="836.60911" cy="660.5" fill="#3f3d56" rx="283" ry="38.5" />
<ellipse cx="310.60911" cy="645.5" rx="170" ry="23.12721" fill="#3f3d56" /> <ellipse cx="310.60911" cy="645.5" fill="#3f3d56" rx="170" ry="23.12721" />
<path <path
d="M494,726.5c90,23,263-30,282-90" d="M494,726.5c90,23,263-30,282-90"
transform="translate(-31.39089 -100.5)"
fill="none" fill="none"
stroke="#2f2e41" stroke="#2f2e41"
stroke-miterlimit="10" stroke-miterlimit="10"
stroke-width="2" stroke-width="2"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M341,359.5s130-36,138,80-107,149-17,172" d="M341,359.5s130-36,138,80-107,149-17,172"
transform="translate(-31.39089 -100.5)"
fill="none" fill="none"
stroke="#2f2e41" stroke="#2f2e41"
stroke-miterlimit="10" stroke-miterlimit="10"
stroke-width="2" stroke-width="2"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M215.40233,637.78332s39.0723-10.82,41.47675,24.04449-32.15951,44.78287-5.10946,51.69566" d="M215.40233,637.78332s39.0723-10.82,41.47675,24.04449-32.15951,44.78287-5.10946,51.69566"
transform="translate(-31.39089 -100.5)"
fill="none" fill="none"
stroke="#2f2e41" stroke="#2f2e41"
stroke-miterlimit="10" stroke-miterlimit="10"
stroke-width="2" stroke-width="2"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M810.09554,663.73988,802.218,714.03505s-38.78182,20.60284-11.51335,21.20881,155.73324,0,155.73324,0,24.84461,0-14.54318-21.81478l-7.87756-52.719Z" d="M810.09554,663.73988,802.218,714.03505s-38.78182,20.60284-11.51335,21.20881,155.73324,0,155.73324,0,24.84461,0-14.54318-21.81478l-7.87756-52.719Z"
transform="translate(-31.39089 -100.5)"
fill="#2f2e41" fill="#2f2e41"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M785.21906,734.69812c6.193-5.51039,16.9989-11.252,16.9989-11.252l7.87756-50.2952,113.9216.10717,7.87756,49.582c9.185,5.08711,14.8749,8.987,18.20362,11.97818,5.05882-1.15422,10.58716-5.44353-18.20362-21.38921l-7.87756-52.719-113.9216,3.02983L802.218,714.03506S769.62985,731.34968,785.21906,734.69812Z" d="M785.21906,734.69812c6.193-5.51039,16.9989-11.252,16.9989-11.252l7.87756-50.2952,113.9216.10717,7.87756,49.582c9.185,5.08711,14.8749,8.987,18.20362,11.97818,5.05882-1.15422,10.58716-5.44353-18.20362-21.38921l-7.87756-52.719-113.9216,3.02983L802.218,714.03506S769.62985,731.34968,785.21906,734.69812Z"
transform="translate(-31.39089 -100.5)"
opacity="0.1" opacity="0.1"
transform="translate(-31.39089 -100.5)"
/> />
<rect <rect
x="578.43291" fill="#2f2e41"
y="212.68859"
width="513.25314"
height="357.51989" height="357.51989"
rx="18.04568" rx="18.04568"
fill="#2f2e41" width="513.25314"
x="578.43291"
y="212.68859"
/> />
<rect <rect
fill="#3f3d56"
height="267.83694"
width="478.71308"
x="595.70294" x="595.70294"
y="231.77652" y="231.77652"
width="478.71308"
height="267.83694"
fill="#3f3d56"
/> />
<circle cx="835.05948" cy="223.29299" r="3.02983" fill="#f2f2f2" /> <circle cx="835.05948" cy="223.29299" fill="#f2f2f2" r="3.02983" />
<path <path
d="M1123.07694,621.32226V652.6628a18.04341,18.04341,0,0,1-18.04568,18.04568H627.86949A18.04341,18.04341,0,0,1,609.8238,652.6628V621.32226Z" d="M1123.07694,621.32226V652.6628a18.04341,18.04341,0,0,1-18.04568,18.04568H627.86949A18.04341,18.04341,0,0,1,609.8238,652.6628V621.32226Z"
transform="translate(-31.39089 -100.5)"
fill="#2f2e41" fill="#2f2e41"
transform="translate(-31.39089 -100.5)"
/> />
<polygon <polygon
points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 651.452 645.651 962.312 645.651 968.978 667.466"
fill="#2f2e41" fill="#2f2e41"
points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 651.452 645.651 962.312 645.651 968.978 667.466"
/> />
<path <path
d="M1125.828,762.03359c-.59383,2.539-2.83591,5.21743-7.90178,7.75032-18.179,9.08949-55.1429-2.42386-55.1429-2.42386s-28.4804-4.84773-28.4804-17.573a22.72457,22.72457,0,0,1,2.49658-1.48459c7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z" d="M1125.828,762.03359c-.59383,2.539-2.83591,5.21743-7.90178,7.75032-18.179,9.08949-55.1429-2.42386-55.1429-2.42386s-28.4804-4.84773-28.4804-17.573a22.72457,22.72457,0,0,1,2.49658-1.48459c7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z"
transform="translate(-31.39089 -100.5)"
fill="#2f2e41" fill="#2f2e41"
transform="translate(-31.39089 -100.5)"
/> />
<path <path
d="M1125.828,762.03359c-22.251,8.526-42.0843,9.1622-62.43871-4.975-10.26507-7.12617-19.59089-8.88955-26.58979-8.75618,7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z" d="M1125.828,762.03359c-22.251,8.526-42.0843,9.1622-62.43871-4.975-10.26507-7.12617-19.59089-8.88955-26.58979-8.75618,7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z"
transform="translate(-31.39089 -100.5)"
opacity="0.1" opacity="0.1"
transform="translate(-31.39089 -100.5)"
/> />
<ellipse <ellipse
cx="1066.53846" cx="1066.53846"
cy="654.13477" cy="654.13477"
fill="#f2f2f2"
rx="7.87756" rx="7.87756"
ry="2.42386" ry="2.42386"
fill="#f2f2f2"
/> />
<circle cx="835.05948" cy="545.66686" r="11.51335" fill="#f2f2f2" /> <circle cx="835.05948" cy="545.66686" fill="#f2f2f2" r="11.51335" />
<polygon <polygon
points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 968.978 667.466"
opacity="0.1" opacity="0.1"
points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 968.978 667.466"
/> />
<rect x="108.60911" y="159" width="208" height="242" fill="#2f2e41" /> <rect fill="#2f2e41" height="242" width="208" x="108.60911" y="159" />
<rect x="87.60911" y="135" width="250" height="86" fill="#3f3d56" /> <rect fill="#3f3d56" height="86" width="250" x="87.60911" y="135" />
<rect x="87.60911" y="237" width="250" height="86" fill="#3f3d56" /> <rect fill="#3f3d56" height="86" width="250" x="87.60911" y="237" />
<rect x="87.60911" y="339" width="250" height="86" fill="#3f3d56" /> <rect fill="#3f3d56" height="86" width="250" x="87.60911" y="339" />
<rect <rect
fill="#6c63ff"
height="16"
opacity="0.4"
width="16"
x="271.60911" x="271.60911"
y="150" y="150"
width="16"
height="16"
fill="#6c63ff"
opacity="0.4"
/> />
<rect <rect
fill="#6c63ff"
height="16"
opacity="0.8"
width="16"
x="294.60911" x="294.60911"
y="150" y="150"
width="16"
height="16"
fill="#6c63ff"
opacity="0.8"
/> />
<rect x="317.60911" y="150" width="16" height="16" fill="#6c63ff" /> <rect fill="#6c63ff" height="16" width="16" x="317.60911" y="150" />
<rect <rect
fill="#6c63ff"
height="16"
opacity="0.4"
width="16"
x="271.60911" x="271.60911"
y="251" y="251"
width="16"
height="16"
fill="#6c63ff"
opacity="0.4"
/> />
<rect <rect
fill="#6c63ff"
height="16"
opacity="0.8"
width="16"
x="294.60911" x="294.60911"
y="251" y="251"
width="16"
height="16"
fill="#6c63ff"
opacity="0.8"
/> />
<rect x="317.60911" y="251" width="16" height="16" fill="#6c63ff" /> <rect fill="#6c63ff" height="16" width="16" x="317.60911" y="251" />
<rect <rect
fill="#6c63ff"
height="16"
opacity="0.4"
width="16"
x="271.60911" x="271.60911"
y="352" y="352"
width="16"
height="16"
fill="#6c63ff"
opacity="0.4"
/> />
<rect <rect
fill="#6c63ff"
height="16"
opacity="0.8"
width="16"
x="294.60911" x="294.60911"
y="352" y="352"
width="16"
height="16"
fill="#6c63ff"
opacity="0.8"
/> />
<rect x="317.60911" y="352" width="16" height="16" fill="#6c63ff" /> <rect fill="#6c63ff" height="16" width="16" x="317.60911" y="352" />
<circle cx="316.60911" cy="538" r="79" fill="#2f2e41" /> <circle cx="316.60911" cy="538" fill="#2f2e41" r="79" />
<rect x="280.60911" y="600" width="24" height="43" fill="#2f2e41" /> <rect fill="#2f2e41" height="43" width="24" x="280.60911" y="600" />
<rect x="328.60911" y="600" width="24" height="43" fill="#2f2e41" /> <rect fill="#2f2e41" height="43" width="24" x="328.60911" y="600" />
<ellipse cx="300.60911" cy="643.5" rx="20" ry="7.5" fill="#2f2e41" /> <ellipse cx="300.60911" cy="643.5" fill="#2f2e41" rx="20" ry="7.5" />
<ellipse cx="348.60911" cy="642.5" rx="20" ry="7.5" fill="#2f2e41" /> <ellipse cx="348.60911" cy="642.5" fill="#2f2e41" rx="20" ry="7.5" />
<circle cx="318.60911" cy="518" r="27" fill="#fff" /> <circle cx="318.60911" cy="518" fill="#fff" r="27" />
<circle cx="318.60911" cy="518" r="9" fill="#3f3d56" /> <circle cx="318.60911" cy="518" fill="#3f3d56" r="9" />
<path <path
d="M271.36733,565.03228c-6.37889-28.56758,14.01185-57.43392,45.544-64.47477s62.2651,10.41,68.644,38.9776-14.51861,39.10379-46.05075,46.14464S277.74622,593.59986,271.36733,565.03228Z" d="M271.36733,565.03228c-6.37889-28.56758,14.01185-57.43392,45.544-64.47477s62.2651,10.41,68.644,38.9776-14.51861,39.10379-46.05075,46.14464S277.74622,593.59986,271.36733,565.03228Z"
transform="translate(-31.39089 -100.5)"
fill="#6c63ff" fill="#6c63ff"
transform="translate(-31.39089 -100.5)"
/> />
<ellipse <ellipse
cx="417.21511" cx="417.21511"
cy="611.34365" cy="611.34365"
fill="#2f2e41"
rx="39.5" rx="39.5"
ry="12.40027" ry="12.40027"
transform="translate(-238.28665 112.98044) rotate(-23.17116)" transform="translate(-238.28665 112.98044) rotate(-23.17116)"
fill="#2f2e41"
/> />
<ellipse <ellipse
cx="269.21511" cx="269.21511"
cy="664.34365" cy="664.34365"
fill="#2f2e41"
rx="39.5" rx="39.5"
ry="12.40027" ry="12.40027"
transform="translate(-271.07969 59.02084) rotate(-23.17116)" transform="translate(-271.07969 59.02084) rotate(-23.17116)"
fill="#2f2e41"
/> />
<path <path
d="M394,661.5c0,7.732-19.90861,23-42,23s-43-14.268-43-22,20.90861-6,43-6S394,653.768,394,661.5Z" d="M394,661.5c0,7.732-19.90861,23-42,23s-43-14.268-43-22,20.90861-6,43-6S394,653.768,394,661.5Z"
transform="translate(-31.39089 -100.5)"
fill="#fff" fill="#fff"
transform="translate(-31.39089 -100.5)"
/> />
</svg> </svg>
</template> </template>

View File

@@ -249,20 +249,20 @@ onMounted(() => {
<li <li
v-for="(item, index) in searchResults" v-for="(item, index) in searchResults"
:key="item.path" :key="item.path"
:data-index="index"
:data-search-item="index"
class="bg-accent flex-center group mb-3 w-full cursor-pointer rounded-lg px-4 py-4"
:class=" :class="
activeIndex === index activeIndex === index
? 'active bg-primary text-primary-foreground text-muted-foreground' ? 'active bg-primary text-primary-foreground text-muted-foreground'
: '' : ''
" "
:data-index="index"
:data-search-item="index"
class="bg-accent flex-center group mb-3 w-full cursor-pointer rounded-lg px-4 py-4"
@mouseenter="handleMouseenter" @mouseenter="handleMouseenter"
> >
<VbenIcon <VbenIcon
fallback
:icon="item.icon" :icon="item.icon"
class="mr-2 size-5 flex-shrink-0" class="mr-2 size-5 flex-shrink-0"
fallback
/> />
<span class="flex-1">{{ item.name }}</span> <span class="flex-1">{{ item.name }}</span>

View File

@@ -35,13 +35,13 @@ function handleClick(value: string) {
<div <div
v-for="item in transitionPreset" v-for="item in transitionPreset"
:key="item" :key="item"
class="outline-box p-2"
:class="{ :class="{
'outline-box-active': transitionName === item, 'outline-box-active': transitionName === item,
}" }"
class="outline-box p-2"
@click="handleClick(item)" @click="handleClick(item)"
> >
<div class="bg-accent h-10 w-12 rounded-md" :class="`${item}-slow`"></div> <div :class="`${item}-slow`" class="bg-accent h-10 w-12 rounded-md"></div>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -45,8 +45,8 @@ const disableItem = computed(() => {
</SwitchItem> </SwitchItem>
<ToggleItem <ToggleItem
v-model="breadcrumbStyleType" v-model="breadcrumbStyleType"
:items="typeItems"
:disabled="disableItem" :disabled="disableItem"
:items="typeItems"
> >
{{ $t('preference.breadcrumb-style') }} {{ $t('preference.breadcrumb-style') }}
</ToggleItem> </ToggleItem>

View File

@@ -41,8 +41,8 @@ const localeItems: SelectListItem[] = [
</SwitchItem> </SwitchItem>
<SelectItem <SelectItem
v-model="headerMode" v-model="headerMode"
:items="localeItems"
:disabled="!headerEnable" :disabled="!headerEnable"
:items="localeItems"
> >
{{ $t('preference.mode') }} {{ $t('preference.mode') }}
</SelectItem> </SelectItem>

View File

@@ -25,8 +25,8 @@ const stylesItems: SelectListItem[] = [
<template> <template>
<ToggleItem <ToggleItem
v-model="navigationStyleType" v-model="navigationStyleType"
:items="stylesItems"
:disabled="disabled" :disabled="disabled"
:items="stylesItems"
> >
{{ $t('preference.navigation-style') }} {{ $t('preference.navigation-style') }}
</ToggleItem> </ToggleItem>

View File

@@ -37,11 +37,11 @@ const slots = useSlots();
<template> <template>
<div <div
class="my-1 flex w-full items-center justify-between rounded-md px-2 py-1"
:class="{ :class="{
'hover:bg-accent': !slots.tip, 'hover:bg-accent': !slots.tip,
'pointer-events-none opacity-50': disabled, 'pointer-events-none opacity-50': disabled,
}" }"
class="my-1 flex w-full items-center justify-between rounded-md px-2 py-1"
> >
<span class="flex items-center text-sm"> <span class="flex items-center text-sm">
<slot></slot> <slot></slot>

View File

@@ -23,10 +23,10 @@ function handleClick() {
<template> <template>
<div <div
class="hover:bg-accent my-1 flex w-full items-center justify-between rounded-md px-2 py-2"
:class="{ :class="{
'pointer-events-none opacity-50': disabled, 'pointer-events-none opacity-50': disabled,
}" }"
class="hover:bg-accent my-1 flex w-full items-center justify-between rounded-md px-2 py-2"
@click="handleClick" @click="handleClick"
> >
<span class="flex items-center text-sm"> <span class="flex items-center text-sm">

View File

@@ -17,19 +17,19 @@ const modelValue = defineModel<string>();
<template> <template>
<div <div
disabled
class="hover:bg-accent flex w-full items-center justify-between rounded-md px-2 py-2"
:class="{ :class="{
'pointer-events-none opacity-50': disabled, 'pointer-events-none opacity-50': disabled,
}" }"
class="hover:bg-accent flex w-full items-center justify-between rounded-md px-2 py-2"
disabled
> >
<span class="text-sm"><slot></slot></span> <span class="text-sm"><slot></slot></span>
<ToggleGroup <ToggleGroup
v-model="modelValue" v-model="modelValue"
class="gap-2"
size="sm"
type="single" type="single"
variant="outline" variant="outline"
size="sm"
class="gap-2"
> >
<template v-for="item in items" :key="item.value"> <template v-for="item in items" :key="item.value">
<ToggleGroupItem <ToggleGroupItem

View File

@@ -10,218 +10,125 @@ import Preferences from './preferences.vue';
</script> </script>
<template> <template>
<Preferences <Preferences
:color-primary-presets="COLOR_PRIMARY_RESETS"
:app-locale="preferences.app.locale"
:app-layout="preferences.app.layout"
:app-dynamic-title="preferences.app.dynamicTitle"
:app-theme-mode="preferences.app.themeMode"
:app-color-gray-mode="preferences.app.colorGrayMode" :app-color-gray-mode="preferences.app.colorGrayMode"
:app-color-weak-mode="preferences.app.colorWeakMode" :app-color-weak-mode="preferences.app.colorWeakMode"
:app-semi-dark-menu="preferences.app.semiDarkMenu"
:app-content-compact="preferences.app.contentCompact" :app-content-compact="preferences.app.contentCompact"
:app-dynamic-title="preferences.app.dynamicTitle"
:app-layout="preferences.app.layout"
:app-locale="preferences.app.locale"
:app-semi-dark-menu="preferences.app.semiDarkMenu"
:app-theme-mode="preferences.app.themeMode"
:breadcrumb-enable="preferences.breadcrumb.enable"
:breadcrumb-hide-only-one="preferences.breadcrumb.hideOnlyOne"
:breadcrumb-home="preferences.breadcrumb.showHome"
:breadcrumb-icon="preferences.breadcrumb.showIcon"
:breadcrumb-style="preferences.breadcrumb.styleType"
:color-primary-presets="COLOR_PRIMARY_RESETS"
:footer-enable="preferences.footer.enable"
:footer-fixed="preferences.footer.fixed"
:header-enable="preferences.header.enable"
:header-mode="preferences.header.mode"
:navigation-accordion="preferences.navigation.accordion"
:navigation-split="preferences.navigation.split"
:navigation-style-type="preferences.navigation.styleType"
:shortcut-keys-enable="preferences.shortcutKeys.enable"
:sidebar-collapse="preferences.sidebar.collapse"
:sidebar-collapse-show-title="preferences.sidebar.collapseShowTitle"
:sidebar-enable="preferences.sidebar.enable"
:tabbar-enable="preferences.tabbar.enable"
:tabbar-show-icon="preferences.tabbar.showIcon"
:theme-color-primary="preferences.theme.colorPrimary"
:transition-enable="preferences.transition.enable" :transition-enable="preferences.transition.enable"
:transition-name="preferences.transition.name" :transition-name="preferences.transition.name"
:transition-progress="preferences.transition.progress" :transition-progress="preferences.transition.progress"
:theme-color-primary="preferences.theme.colorPrimary" @update:app-color-gray-mode="
:sidebar-enable="preferences.sidebar.enable" (val) => updatePreferences({ app: { colorGrayMode: val } })
:sidebar-collapse="preferences.sidebar.collapse" "
:sidebar-collapse-show-title="preferences.sidebar.collapseShowTitle" @update:app-color-weak-mode="
:header-enable="preferences.header.enable" (val) => updatePreferences({ app: { colorWeakMode: val } })
:header-mode="preferences.header.mode" "
:breadcrumb-enable="preferences.breadcrumb.enable" @update:app-content-compact="
:breadcrumb-style="preferences.breadcrumb.styleType" (val) => updatePreferences({ app: { contentCompact: val } })
:breadcrumb-icon="preferences.breadcrumb.showIcon" "
:breadcrumb-home="preferences.breadcrumb.showHome" @update:app-dynamic-title="
:breadcrumb-hide-only-one="preferences.breadcrumb.hideOnlyOne" (val) => updatePreferences({ app: { dynamicTitle: val } })
:tabbar-enable="preferences.tabbar.enable" "
:tabbar-show-icon="preferences.tabbar.showIcon" @update:app-layout="(val) => updatePreferences({ app: { layout: val } })"
:navigation-accordion="preferences.navigation.accordion"
:navigation-style-type="preferences.navigation.styleType"
:navigation-split="preferences.navigation.split"
:footer-enable="preferences.footer.enable"
:footer-fixed="preferences.footer.fixed"
:shortcut-keys-enable="preferences.shortcutKeys.enable"
@update:app-locale=" @update:app-locale="
(val) => { (val) => {
updatePreferences({ updatePreferences({ app: { locale: val } });
app: { locale: val },
});
loadLocaleMessages(val); loadLocaleMessages(val);
} }
" "
@update:app-layout=" @update:app-semi-dark-menu="
(val) => (val) => updatePreferences({ app: { semiDarkMenu: val } })
updatePreferences({
app: { layout: val },
})
"
@update:app-dynamic-title="
(val) =>
updatePreferences({
app: { dynamicTitle: val },
})
" "
@update:app-theme-mode=" @update:app-theme-mode="
(val) => (val) => updatePreferences({ app: { themeMode: val } })
updatePreferences({
app: { themeMode: val },
})
"
@update:app-color-gray-mode="
(val) =>
updatePreferences({
app: { colorGrayMode: val },
})
"
@update:app-color-weak-mode="
(val) =>
updatePreferences({
app: { colorWeakMode: val },
})
"
@update:app-semi-dark-menu="
(val) =>
updatePreferences({
app: { semiDarkMenu: val },
})
"
@update:app-content-compact="
(val) =>
updatePreferences({
app: { contentCompact: val },
})
"
@update:transition-enable="
(val) =>
updatePreferences({
transition: { enable: val },
})
"
@update:transition-name="
(val) =>
updatePreferences({
transition: { name: val },
})
"
@update:transition-progress="
(val) =>
updatePreferences({
transition: { progress: val },
})
"
@update:theme-color-primary="
(val) =>
updatePreferences({
theme: { colorPrimary: val },
})
"
@update:sidebar-enable="
(val) =>
updatePreferences({
sidebar: { enable: val },
})
"
@update:sidebar-collapse="
(val) =>
updatePreferences({
sidebar: { collapse: val },
})
"
@update:sidebar-collapse-show-title="
(val) =>
updatePreferences({
sidebar: { collapseShowTitle: val },
})
"
@update:header-enable="
(val) =>
updatePreferences({
header: { enable: val },
})
"
@update:header-mode="
(val) =>
updatePreferences({
header: { mode: val },
})
" "
@update:breadcrumb-enable=" @update:breadcrumb-enable="
(val) => (val) => updatePreferences({ breadcrumb: { enable: val } })
updatePreferences({
breadcrumb: { enable: val },
})
"
@update:breadcrumb-style-type="
(val) =>
updatePreferences({
breadcrumb: { styleType: val },
})
"
@update:breadcrumb-show-icon="
(val) =>
updatePreferences({
breadcrumb: { showIcon: val },
})
"
@update:breadcrumb-show-home="
(val) =>
updatePreferences({
breadcrumb: { showHome: val },
})
" "
@update:breadcrumb-hide-only-one=" @update:breadcrumb-hide-only-one="
(val) => (val) => updatePreferences({ breadcrumb: { hideOnlyOne: val } })
updatePreferences({
breadcrumb: { hideOnlyOne: val },
})
" "
@update:tabbar-enable=" @update:breadcrumb-show-home="
(val) => (val) => updatePreferences({ breadcrumb: { showHome: val } })
updatePreferences({
tabbar: { enable: val },
})
" "
@update:tabbar-show-icon=" @update:breadcrumb-show-icon="
(val) => (val) => updatePreferences({ breadcrumb: { showIcon: val } })
updatePreferences({
tabbar: { showIcon: val },
})
" "
@update:navigation-accordion=" @update:breadcrumb-style-type="
(val) => (val) => updatePreferences({ breadcrumb: { styleType: val } })
updatePreferences({
navigation: { accordion: val },
})
"
@update:navigation-style-type="
(val) =>
updatePreferences({
navigation: { styleType: val },
})
"
@update:navigation-split="
(val) =>
updatePreferences({
navigation: { split: val },
})
" "
@update:footer-enable=" @update:footer-enable="
(val) => (val) => updatePreferences({ footer: { enable: val } })
updatePreferences({
footer: { enable: val },
})
" "
@update:footer-fixed=" @update:footer-fixed="
(val) => (val) => updatePreferences({ footer: { fixed: val } })
updatePreferences({ "
footer: { fixed: val }, @update:header-enable="
}) (val) => updatePreferences({ header: { enable: val } })
"
@update:header-mode="(val) => updatePreferences({ header: { mode: val } })"
@update:navigation-accordion="
(val) => updatePreferences({ navigation: { accordion: val } })
"
@update:navigation-split="
(val) => updatePreferences({ navigation: { split: val } })
"
@update:navigation-style-type="
(val) => updatePreferences({ navigation: { styleType: val } })
" "
@update:shortcut-keys-enable=" @update:shortcut-keys-enable="
(val) => (val) => updatePreferences({ shortcutKeys: { enable: val } })
updatePreferences({ "
shortcutKeys: { enable: val }, @update:sidebar-collapse="
}) (val) => updatePreferences({ sidebar: { collapse: val } })
"
@update:sidebar-collapse-show-title="
(val) => updatePreferences({ sidebar: { collapseShowTitle: val } })
"
@update:sidebar-enable="
(val) => updatePreferences({ sidebar: { enable: val } })
"
@update:tabbar-enable="
(val) => updatePreferences({ tabbar: { enable: val } })
"
@update:tabbar-show-icon="
(val) => updatePreferences({ tabbar: { showIcon: val } })
"
@update:theme-color-primary="
(val) => updatePreferences({ theme: { colorPrimary: val } })
"
@update:transition-enable="
(val) => updatePreferences({ transition: { enable: val } })
"
@update:transition-name="
(val) => updatePreferences({ transition: { name: val } })
"
@update:transition-progress="
(val) => updatePreferences({ transition: { progress: val } })
" "
/> />
</template> </template>

View File

@@ -172,9 +172,9 @@ function handleReset() {
</template> </template>
<template #extra> <template #extra>
<VbenIconButton <VbenIconButton
class="relative"
:disabled="!diffPreference" :disabled="!diffPreference"
:tooltip="$t('preference.reset-tip')" :tooltip="$t('preference.reset-tip')"
class="relative"
> >
<span <span
v-if="diffPreference" v-if="diffPreference"
@@ -216,9 +216,9 @@ function handleReset() {
<Block :title="$t('preference.sidebar')"> <Block :title="$t('preference.sidebar')">
<Sidebar <Sidebar
v-model:sidebar-enable="sidebarEnable"
v-model:sidebar-collapse="sidebarCollapse"
v-model:side-collapse-show-title="sidebarCollapseShowTitle" v-model:side-collapse-show-title="sidebarCollapseShowTitle"
v-model:sidebar-collapse="sidebarCollapse"
v-model:sidebar-enable="sidebarEnable"
:disabled="!isSideMode" :disabled="!isSideMode"
/> />
</Block> </Block>
@@ -233,9 +233,9 @@ function handleReset() {
<Block :title="$t('preference.navigation-menu')"> <Block :title="$t('preference.navigation-menu')">
<Navigation <Navigation
v-model:navigation-style-type="navigationStyleType"
v-model:navigation-split="navigationSplit"
v-model:navigation-accordion="navigationAccordion" v-model:navigation-accordion="navigationAccordion"
v-model:navigation-split="navigationSplit"
v-model:navigation-style-type="navigationStyleType"
:disabled="isFullContent" :disabled="isFullContent"
:disabled-navigation-split="!isMixedNav" :disabled-navigation-split="!isMixedNav"
/> />
@@ -244,10 +244,10 @@ function handleReset() {
<Block :title="$t('preference.breadcrumb')"> <Block :title="$t('preference.breadcrumb')">
<Breadcrumb <Breadcrumb
v-model:breadcrumb-enable="breadcrumbEnable" v-model:breadcrumb-enable="breadcrumbEnable"
v-model:breadcrumb-hide-only-one="breadcrumbHideOnlyOne"
v-model:breadcrumb-show-home="breadcrumbShowHome"
v-model:breadcrumb-show-icon="breadcrumbShowIcon" v-model:breadcrumb-show-icon="breadcrumbShowIcon"
v-model:breadcrumb-style-type="breadcrumbStyleType" v-model:breadcrumb-style-type="breadcrumbStyleType"
v-model:breadcrumb-show-home="breadcrumbShowHome"
v-model:breadcrumb-hide-only-one="breadcrumbHideOnlyOne"
:disabled=" :disabled="
!showBreadcrumbConfig || !(isSideNav || isSideMixedNav) !showBreadcrumbConfig || !(isSideNav || isSideMixedNav)
" "
@@ -270,17 +270,17 @@ function handleReset() {
<template #general> <template #general>
<Block :title="$t('preference.general')"> <Block :title="$t('preference.general')">
<General <General
v-model:app-locale="appLocale"
v-model:app-dynamic-title="appDynamicTitle" v-model:app-dynamic-title="appDynamicTitle"
v-model:app-locale="appLocale"
v-model:shortcut-keys-enable="shortcutKeysEnable" v-model:shortcut-keys-enable="shortcutKeysEnable"
/> />
</Block> </Block>
<Block :title="$t('preference.animation')"> <Block :title="$t('preference.animation')">
<Animation <Animation
v-model:transition-progress="transitionProgress"
v-model:transition-name="transitionName"
v-model:transition-enable="transitionEnable" v-model:transition-enable="transitionEnable"
v-model:transition-name="transitionName"
v-model:transition-progress="transitionProgress"
/> />
</Block> </Block>
</template> </template>
@@ -306,10 +306,10 @@ function handleReset() {
<template #footer> <template #footer>
<VbenButton <VbenButton
class="mx-6 w-full"
variant="default"
size="sm"
:disabled="!diffPreference" :disabled="!diffPreference"
class="mx-6 w-full"
size="sm"
variant="default"
@click="handleCopy" @click="handleCopy"
> >
<IcRoundFolderCopy class="mr-2 size-3" /> <IcRoundFolderCopy class="mr-2 size-3" />

View File

@@ -11,8 +11,8 @@ defineOptions({
<template> <template>
<VbenButton <VbenButton
class="bg-primary flex-col-center h-9 w-9 cursor-pointer rounded-l-md rounded-r-none border-none"
:title="$t('preference.preferences')" :title="$t('preference.preferences')"
class="bg-primary flex-col-center h-9 w-9 cursor-pointer rounded-l-md rounded-r-none border-none"
> >
<IconSetting class="text-lg" /> <IconSetting class="text-lg" />
</VbenButton> </VbenButton>

View File

@@ -55,7 +55,7 @@ const PRESETS = [
</script> </script>
<template> <template>
<div> <div>
<VbenTooltip side="bottom" :disabled="!shouldOnHover"> <VbenTooltip :disabled="!shouldOnHover" side="bottom">
<template #trigger> <template #trigger>
<ThemeButton <ThemeButton
:model-value="isDark" :model-value="isDark"
@@ -65,9 +65,9 @@ const PRESETS = [
</template> </template>
<ToggleGroup <ToggleGroup
:model-value="preferences.app.themeMode" :model-value="preferences.app.themeMode"
class="gap-2"
type="single" type="single"
variant="outline" variant="outline"
class="gap-2"
@update:model-value=" @update:model-value="
(val) => (val) =>
updatePreferences({ app: { themeMode: val as ThemeModeType } }) updatePreferences({ app: { themeMode: val as ThemeModeType } })

View File

@@ -110,10 +110,10 @@ if (shortcutKeys.value) {
<template> <template>
<VbenAlertDialog <VbenAlertDialog
v-model:open="openDialog" v-model:open="openDialog"
:content="$t('widgets.logout-tip')"
:title="$t('common.prompt')"
:cancel-text="$t('common.cancel')" :cancel-text="$t('common.cancel')"
:content="$t('widgets.logout-tip')"
:submit-text="$t('common.confirm')" :submit-text="$t('common.confirm')"
:title="$t('common.prompt')"
@submit="handleSubmitLogout" @submit="handleSubmitLogout"
/> />

View File

@@ -28,12 +28,12 @@ const appName = computed(() => preferences.app.name);
<div class="absolute left-0 top-0 z-10 flex flex-1"> <div class="absolute left-0 top-0 z-10 flex flex-1">
<div <div
class="text-foreground ml-4 mt-4 flex flex-1 items-center sm:left-6 sm:top-6"
:class=" :class="
authPanelLeft || authPanelCenter authPanelLeft || authPanelCenter
? 'lg:text-foreground' ? 'lg:text-foreground'
: 'lg:text-white' : 'lg:text-white'
" "
class="text-foreground ml-4 mt-4 flex flex-1 items-center sm:left-6 sm:top-6"
> >
<img <img
:alt="appName" :alt="appName"

View File

@@ -14,7 +14,7 @@ defineOptions({
</slot> </slot>
<RouterView v-slot="{ Component, route }"> <RouterView v-slot="{ Component, route }">
<Transition name="slide-right" mode="out-in" appear> <Transition appear mode="out-in" name="slide-right">
<KeepAlive :include="['Login']"> <KeepAlive :include="['Login']">
<component <component
:is="Component" :is="Component"

View File

@@ -41,11 +41,11 @@ function getTransitionName(route: RouteLocationNormalizedLoaded) {
<template> <template>
<IFrameRouterView /> <IFrameRouterView />
<RouterView v-slot="{ Component, route }"> <RouterView v-slot="{ Component, route }">
<Transition :name="getTransitionName(route)" mode="out-in" appear> <Transition :name="getTransitionName(route)" appear mode="out-in">
<KeepAlive <KeepAlive
v-if="keepAlive" v-if="keepAlive"
:include="getCacheTabs"
:exclude="getExcludeTabs" :exclude="getExcludeTabs"
:include="getCacheTabs"
> >
<component <component
:is="Component" :is="Component"

View File

@@ -31,9 +31,9 @@ const accessStore = useAccessStore();
</div> </div>
<div class="flex h-full min-w-0 flex-shrink-0 items-center"> <div class="flex h-full min-w-0 flex-shrink-0 items-center">
<GlobalSearch <GlobalSearch
class="mr-4"
:enable-shortcut-key="preferences.shortcutKeys.enable" :enable-shortcut-key="preferences.shortcutKeys.enable"
:menus="accessStore.getAccessMenus" :menus="accessStore.getAccessMenus"
class="mr-4"
/> />
<ThemeToggle class="mr-2" /> <ThemeToggle class="mr-2" />
<LanguageToggle class="mr-2" /> <LanguageToggle class="mr-2" />

View File

@@ -103,56 +103,38 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
<template> <template>
<VbenAdminLayout <VbenAdminLayout
v-model:side-extra-visible="extraVisible" v-model:side-extra-visible="extraVisible"
:side-extra-collapse="preferences.sidebar.extraCollapse"
:side-expand-on-hover="preferences.sidebar.expandOnHover"
:side-collapse="preferences.sidebar.collapse"
:side-collapse-show-title="preferences.sidebar.collapseShowTitle"
:content-compact="preferences.app.contentCompact" :content-compact="preferences.app.contentCompact"
:footer-enable="preferences.footer.enable"
:footer-fixed="preferences.footer.fixed"
:header-hidden="preferences.header.hidden"
:header-mode="preferences.header.mode"
:header-visible="preferences.header.enable"
:is-mobile="preferences.app.isMobile" :is-mobile="preferences.app.isMobile"
:layout="layout" :layout="layout"
:header-mode="preferences.header.mode" :side-collapse="preferences.sidebar.collapse"
:footer-fixed="preferences.footer.fixed" :side-collapse-show-title="preferences.sidebar.collapseShowTitle"
:side-expand-on-hover="preferences.sidebar.expandOnHover"
:side-extra-collapse="preferences.sidebar.extraCollapse"
:side-hidden="preferences.sidebar.hidden"
:side-semi-dark="preferences.app.semiDarkMenu" :side-semi-dark="preferences.app.semiDarkMenu"
:side-theme="theme" :side-theme="theme"
:side-hidden="preferences.sidebar.hidden"
:side-visible="sideVisible" :side-visible="sideVisible"
:footer-visible="preferences.footer.enable"
:header-visible="preferences.header.enable"
:header-hidden="preferences.header.hidden"
:side-width="preferences.sidebar.width" :side-width="preferences.sidebar.width"
:tabs-visible="preferences.tabbar.enable" :tabs-visible="preferences.tabbar.enable"
@update:side-extra-collapse=" @side-mouse-leave="handleSideMouseLeave"
(value: boolean) => @update:side-collapse="
updatePreferences({ (value: boolean) => updatePreferences({ sidebar: { collapse: value } })
sidebar: {
extraCollapse: value,
},
})
" "
@update:side-expand-on-hover=" @update:side-expand-on-hover="
(value: boolean) => (value: boolean) =>
updatePreferences({ updatePreferences({ sidebar: { expandOnHover: value } })
sidebar: {
expandOnHover: value,
},
})
" "
@update:side-collapse=" @update:side-extra-collapse="
(value: boolean) => (value: boolean) =>
updatePreferences({ updatePreferences({ sidebar: { extraCollapse: value } })
sidebar: {
collapse: value,
},
})
" "
@side-mouse-leave="handleSideMouseLeave"
@update:side-visible=" @update:side-visible="
(value: boolean) => (value: boolean) => updatePreferences({ sidebar: { enable: value } })
updatePreferences({
sidebar: {
enable: value,
},
})
" "
> >
<template v-if="preferences.app.showPreference" #preferences> <template v-if="preferences.app.showPreference" #preferences>
@@ -167,12 +149,12 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
<!-- logo --> <!-- logo -->
<template #logo> <template #logo>
<VbenLogo <VbenLogo
:alt="preferences.app.name"
:class="logoClass"
:collapse="logoCollapse" :collapse="logoCollapse"
:src="preferences.logo.source" :src="preferences.logo.source"
:text="preferences.app.name" :text="preferences.app.name"
:theme="showHeaderNav ? headerMenuTheme : theme" :theme="showHeaderNav ? headerMenuTheme : theme"
:alt="preferences.app.name"
:class="logoClass"
/> />
</template> </template>
<!-- 头部区域 --> <!-- 头部区域 -->
@@ -184,19 +166,19 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
> >
<Breadcrumb <Breadcrumb
:hide-when-only-one="preferences.breadcrumb.hideOnlyOne" :hide-when-only-one="preferences.breadcrumb.hideOnlyOne"
:type="preferences.breadcrumb.styleType"
:show-icon="preferences.breadcrumb.showIcon"
:show-home="preferences.breadcrumb.showHome" :show-home="preferences.breadcrumb.showHome"
:show-icon="preferences.breadcrumb.showIcon"
:type="preferences.breadcrumb.styleType"
/> />
</template> </template>
<template v-if="showHeaderNav" #menu> <template v-if="showHeaderNav" #menu>
<LayoutMenu <LayoutMenu
class="w-full"
:rounded="isMenuRounded"
mode="horizontal"
:theme="headerMenuTheme"
:menus="wrapperMenus(headerMenus)"
:default-active="headerActive" :default-active="headerActive"
:menus="wrapperMenus(headerMenus)"
:rounded="isMenuRounded"
:theme="headerMenuTheme"
class="w-full"
mode="horizontal"
@select="handleMenuSelect" @select="handleMenuSelect"
/> />
</template> </template>
@@ -211,44 +193,44 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
<!-- 侧边菜单区域 --> <!-- 侧边菜单区域 -->
<template #menu> <template #menu>
<LayoutMenu <LayoutMenu
mode="vertical"
:accordion="preferences.navigation.accordion" :accordion="preferences.navigation.accordion"
:rounded="isMenuRounded"
:collapse-show-title="preferences.sidebar.collapseShowTitle"
:collapse="preferences.sidebar.collapse" :collapse="preferences.sidebar.collapse"
:theme="theme" :collapse-show-title="preferences.sidebar.collapseShowTitle"
:menus="wrapperMenus(sideMenus)"
:default-active="sideActive" :default-active="sideActive"
:menus="wrapperMenus(sideMenus)"
:rounded="isMenuRounded"
:theme="theme"
mode="vertical"
@select="handleMenuSelect" @select="handleMenuSelect"
/> />
</template> </template>
<template #mixed-menu> <template #mixed-menu>
<LayoutMixedMenu <LayoutMixedMenu
:rounded="isMenuRounded"
:collapse="!preferences.sidebar.collapseShowTitle"
:active-path="extraActiveMenu" :active-path="extraActiveMenu"
:collapse="!preferences.sidebar.collapseShowTitle"
:rounded="isMenuRounded"
:theme="theme" :theme="theme"
@select="handleMixedMenuSelect"
@default-select="handleDefaultSelect" @default-select="handleDefaultSelect"
@enter="handleMenuMouseEnter" @enter="handleMenuMouseEnter"
@select="handleMixedMenuSelect"
/> />
</template> </template>
<!-- 侧边额外区域 --> <!-- 侧边额外区域 -->
<template #side-extra> <template #side-extra>
<LayoutExtraMenu <LayoutExtraMenu
:accordion="preferences.navigation.accordion" :accordion="preferences.navigation.accordion"
:rounded="isMenuRounded"
:menus="wrapperMenus(extraMenus)"
:collapse="preferences.sidebar.extraCollapse" :collapse="preferences.sidebar.extraCollapse"
:menus="wrapperMenus(extraMenus)"
:rounded="isMenuRounded"
:theme="theme" :theme="theme"
/> />
</template> </template>
<template #side-extra-title> <template #side-extra-title>
<VbenLogo <VbenLogo
v-if="preferences.logo.enable" v-if="preferences.logo.enable"
:alt="preferences.app.name"
:text="preferences.app.name" :text="preferences.app.name"
:theme="theme" :theme="theme"
:alt="preferences.app.name"
/> />
</template> </template>

View File

@@ -27,11 +27,11 @@ async function handleSelect(key: string) {
<template> <template>
<Menu <Menu
:rounded="rounded"
:accordion="accordion" :accordion="accordion"
:collapse="collapse" :collapse="collapse"
:default-active="route.path" :default-active="route.path"
:menus="menus" :menus="menus"
:rounded="rounded"
:theme="theme" :theme="theme"
mode="vertical" mode="vertical"
@select="handleSelect" @select="handleSelect"

View File

@@ -23,14 +23,14 @@ function handleMenuSelect(key: string) {
<template> <template>
<Menu <Menu
:rounded="rounded"
:collapse-show-title="collapseShowTitle"
:collapse="collapse"
:accordion="accordion" :accordion="accordion"
:collapse="collapse"
:collapse-show-title="collapseShowTitle"
:default-active="defaultActive" :default-active="defaultActive"
:menus="menus" :menus="menus"
:theme="theme"
:mode="mode" :mode="mode"
:rounded="rounded"
:theme="theme"
@select="handleMenuSelect" @select="handleMenuSelect"
/> />
</template> </template>

View File

@@ -42,12 +42,12 @@ onBeforeMount(() => {
<template> <template>
<NormalMenu <NormalMenu
:rounded="rounded" :active-path="activePath"
:collapse="collapse" :collapse="collapse"
:menus="menus" :menus="menus"
:active-path="activePath" :rounded="rounded"
:theme="theme" :theme="theme"
@select="handleSelect"
@enter="(menu) => emit('enter', menu)" @enter="(menu) => emit('enter', menu)"
@select="handleSelect"
/> />
</template> </template>

View File

@@ -21,12 +21,12 @@ const {
<template> <template>
<TabsView <TabsView
:active="currentActive"
:menus="createContextMenus"
:show-icon="showIcon" :show-icon="showIcon"
:tabs="currentTabs" :tabs="currentTabs"
:menus="createContextMenus"
:active="currentActive"
@update:active="handleClick"
@close="handleClose" @close="handleClose"
@un-push-pin="handleUnPushPin" @un-push-pin="handleUnPushPin"
@update:active="handleClick"
/> />
</template> </template>

View File

@@ -75,15 +75,15 @@ function handleSelect(path: string) {
<VbenBreadcrumb <VbenBreadcrumb
v-if="type === 'normal'" v-if="type === 'normal'"
:breadcrumbs="breadcrumbs" :breadcrumbs="breadcrumbs"
class="ml-2"
:show-icon="showIcon" :show-icon="showIcon"
class="ml-2"
@select="handleSelect" @select="handleSelect"
/> />
<VbenBackgroundBreadcrumb <VbenBackgroundBreadcrumb
v-if="type === 'background'" v-if="type === 'background'"
:breadcrumbs="breadcrumbs" :breadcrumbs="breadcrumbs"
class="ml-2"
:show-icon="showIcon" :show-icon="showIcon"
class="ml-2"
@select="handleSelect" @select="handleSelect"
/> />
</template> </template>

View File

@@ -70,8 +70,8 @@ function showSpinning(index: number) {
{{ iframeRoutes.length }} {{ iframeRoutes.length }}
<template v-for="(item, index) in iframeRoutes" :key="item.fullPath"> <template v-for="(item, index) in iframeRoutes" :key="item.fullPath">
<div <div
v-show="routeShow(item)"
v-if="canRender(item)" v-if="canRender(item)"
v-show="routeShow(item)"
class="relative size-full" class="relative size-full"
> >
<Spinner :spinning="showSpinning(index)" /> <Spinner :spinning="showSpinning(index)" />