mirror of
https://github.com/xiangshu233/vue3-vant4-mobile.git
synced 2026-04-29 15:08:11 +08:00
refactor: ♻️ 升级依赖并重构导航与主题交互
升级核心依赖与构建链路(Vite/Vue/Pinia/VueUse/Vant 等)并完成兼容调整 Vibe Coding 了一个导航组件 FloatingNavBar 修复暗黑模式 switch 动画异常:统一 useDark 行为并设置 disableTransition: false,恢复 Vant Switch 过渡动画 调整亮色模式下页面背景与卡片层次(以边框+轻阴影为主),降低过强对比并提升一致性 我的页面入口 icon 统一为线性风格
This commit is contained in:
parent
6e776c52e2
commit
fbc12f02f9
3
.gitignore
vendored
3
.gitignore
vendored
@ -23,4 +23,5 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
/components.d.ts
|
||||
/components.d.ts
|
||||
.agents/
|
||||
skills-lock.json
|
||||
|
||||
48
package.json
48
package.json
@ -18,7 +18,7 @@
|
||||
"url": "https://github.com/xiangshu233/vue3-vant4-mobile/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.9.0 || >=21.7.1",
|
||||
"node": "^20.19.0 || >=22.12.0",
|
||||
"pnpm": ">=8.15.4"
|
||||
},
|
||||
"scripts": {
|
||||
@ -40,44 +40,44 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@unocss/reset": "^0.58.5",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
"axios": "^1.4.0",
|
||||
"date-fns": "^3.0.6",
|
||||
"echarts": "^5.4.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"pinia": "^3.0.4",
|
||||
"pinia-plugin-persistedstate": "^4.7.1",
|
||||
"qs": "^6.11.2",
|
||||
"vant": "^4.8.1",
|
||||
"vue": "^3.3.13",
|
||||
"vue-router": "4.2.5"
|
||||
"vant": "^4.9.22",
|
||||
"vue": "^3.5.30",
|
||||
"vue-router": "^5.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.6.3",
|
||||
"@commitlint/cli": "^18.4.3",
|
||||
"@commitlint/config-conventional": "^18.4.3",
|
||||
"@iconify/json": "^2.2.188",
|
||||
"@oxc-parser/binding-win32-x64-msvc": "0.115.0",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/mockjs": "^1.0.10",
|
||||
"@types/node": "^20.10.5",
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qs": "^6.9.11",
|
||||
"@unocss/eslint-plugin": "^0.58.4",
|
||||
"@unocss/preset-icons": "^0.58.5",
|
||||
"@unocss/preset-rem-to-px": "^0.58.5",
|
||||
"@unocss/transformer-directives": "^0.58.4",
|
||||
"@unocss/transformer-variant-group": "^0.58.4",
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"@unocss/eslint-plugin": "^66.6.7",
|
||||
"@unocss/preset-icons": "^66.6.7",
|
||||
"@unocss/preset-rem-to-px": "^66.6.7",
|
||||
"@unocss/reset": "^66.6.7",
|
||||
"@unocss/transformer-directives": "^66.6.7",
|
||||
"@unocss/transformer-variant-group": "^66.6.7",
|
||||
"@vitejs/plugin-vue": "^6.0.5",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-git": "^1.8.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-format": "^0.1.0",
|
||||
"tsx": "^3.0.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"less": "^4.2.0",
|
||||
"lint-staged": "^15.2.0",
|
||||
@ -89,16 +89,18 @@
|
||||
"rollup": "^4.9.1",
|
||||
"rollup-plugin-visualizer": "^5.11.0",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"typescript": "^5.3.3",
|
||||
"unocss": "^0.58.5",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.0.10",
|
||||
"terser": "^5.46.1",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.3",
|
||||
"unocss": "^66.6.7",
|
||||
"unplugin-auto-import": "^21.0.0",
|
||||
"unplugin-vue-components": "^32.0.0",
|
||||
"vite": "^8.0.2",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-mock": "^2.9.8",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vue-tsc": "^1.8.27"
|
||||
"vue-tsc": "^3.2.6"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"pre-commit": "pnpm lint-staged",
|
||||
|
||||
3795
pnpm-lock.yaml
generated
3795
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<vanConfigProvider :theme="getDarkMode" :theme-vars="getThemeVars()">
|
||||
<routerView v-slot="{ Component }">
|
||||
<RouterView v-slot="{ Component }">
|
||||
<div class="absolute bottom-0 top-0 w-full overflow-hidden">
|
||||
<transition :name="getTransitionName" mode="out-in" appear>
|
||||
<keep-alive v-if="keepAliveComponents" :include="keepAliveComponents">
|
||||
<KeepAlive v-if="keepAliveComponents" :include="keepAliveComponents">
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</KeepAlive>
|
||||
</transition>
|
||||
</div>
|
||||
</routerView>
|
||||
</RouterView>
|
||||
</vanConfigProvider>
|
||||
</template>
|
||||
|
||||
|
||||
@ -4,44 +4,35 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import type { CSSProperties } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SvgIcon',
|
||||
props: {
|
||||
prefix: {
|
||||
type: String,
|
||||
default: 'icon',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 16,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#333',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
|
||||
defineOptions({ name: 'SvgIcon' })
|
||||
|
||||
const getStyle = computed((): CSSProperties => {
|
||||
const { size } = props
|
||||
let s = `${size}`
|
||||
s = `${s.replace('px', '')}px`
|
||||
return {
|
||||
width: s,
|
||||
height: s,
|
||||
}
|
||||
})
|
||||
|
||||
return { symbolId, getStyle }
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
prefix?: string
|
||||
name: string
|
||||
size?: number | string
|
||||
color?: string
|
||||
}>(),
|
||||
{
|
||||
prefix: 'icon',
|
||||
size: 16,
|
||||
color: '#333',
|
||||
},
|
||||
)
|
||||
|
||||
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
|
||||
|
||||
const getStyle = computed((): CSSProperties => {
|
||||
const { size } = props
|
||||
let s = `${size}`
|
||||
s = `${s.replace('px', '')}px`
|
||||
return {
|
||||
width: s,
|
||||
height: s,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
535
src/layout/components/FloatingNavBar.vue
Normal file
535
src/layout/components/FloatingNavBar.vue
Normal file
@ -0,0 +1,535 @@
|
||||
<template>
|
||||
<div class="floating-toolbar-wrap">
|
||||
<nav
|
||||
ref="toolbarRef"
|
||||
class="floating-toolbar"
|
||||
:class="{ dark: isDarkTheme }"
|
||||
:style="toolbarCssVars"
|
||||
aria-label="主导航"
|
||||
>
|
||||
<div class="ambient-glow" />
|
||||
<div class="film-grain" />
|
||||
|
||||
<div
|
||||
ref="indicatorRef"
|
||||
class="active-indicator"
|
||||
:style="{
|
||||
transform: `translateX(${indicatorX}px)`,
|
||||
opacity: activeNavIndex >= 0 ? 1 : 0,
|
||||
}"
|
||||
>
|
||||
<div class="ring-glow" />
|
||||
<div class="ring-clip">
|
||||
<div class="ring-spin" />
|
||||
</div>
|
||||
<div class="inner-plate" />
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-for="(item, idx) in navItems"
|
||||
:key="item.path"
|
||||
:ref="(el) => setNavRef(el, idx)"
|
||||
type="button"
|
||||
class="nav-btn"
|
||||
:class="{
|
||||
'active': idx === activeNavIndex,
|
||||
'with-divider': idx < navItems.length - 1,
|
||||
'nav-bounce': navBounceIndex === idx,
|
||||
}"
|
||||
:aria-label="item.label"
|
||||
@click="handleNavClick(idx, item.path)"
|
||||
>
|
||||
<i :class="item.icon" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="props.showDarkModeToggle"
|
||||
type="button"
|
||||
class="nav-btn toggle-btn"
|
||||
:class="{ bounce: toggleBouncing }"
|
||||
aria-label="切换主题"
|
||||
@click="toggleTheme"
|
||||
>
|
||||
<span class="toggle-icon-wrap">
|
||||
<i class="i-ph:sun-dim sun-icon" :class="{ hidden: darkModel }" />
|
||||
<i class="i-ph:moon moon-icon" :class="{ show: darkModel }" />
|
||||
</span>
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
|
||||
interface NavItem {
|
||||
label: string
|
||||
path: string
|
||||
icon: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items?: NavItem[]
|
||||
showDarkModeToggle?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
items: () => [
|
||||
{ label: 'Home', path: '/dashboard/index', icon: 'i-ph:house-line' },
|
||||
{ label: 'Search', path: '/message/index', icon: 'i-ph:magnifying-glass' },
|
||||
{ label: 'User', path: '/my/index', icon: 'i-ph:user-circle' },
|
||||
],
|
||||
showDarkModeToggle: true,
|
||||
})
|
||||
|
||||
const designStore = useDesignSettingStore()
|
||||
const currentRoute = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const navItems = computed(() => props.items)
|
||||
|
||||
const activeNavIndex = computed(() => {
|
||||
const path = currentRoute.path
|
||||
const items = navItems.value
|
||||
if (items.length === 0) {
|
||||
return -1
|
||||
}
|
||||
const index = items.findIndex((item) => {
|
||||
const basePath = item.path.replace(/\/index$/, '')
|
||||
return path === item.path || path.startsWith(basePath)
|
||||
})
|
||||
return index >= 0 ? index : 0
|
||||
})
|
||||
|
||||
const toolbarRef = ref<HTMLElement | null>(null)
|
||||
const indicatorRef = ref<HTMLElement | null>(null)
|
||||
const navRefs = ref<(HTMLElement | null)[]>([])
|
||||
const indicatorX = ref(0)
|
||||
|
||||
const isDark = useDark({
|
||||
valueDark: 'dark',
|
||||
valueLight: 'light',
|
||||
disableTransition: false,
|
||||
})
|
||||
|
||||
const darkModel = computed({
|
||||
get: () => isDark.value || designStore.darkMode === 'dark',
|
||||
set: (value: boolean) => {
|
||||
isDark.value = value
|
||||
designStore.setDarkMode(value ? 'dark' : 'light')
|
||||
},
|
||||
})
|
||||
const isDarkTheme = computed(() => darkModel.value)
|
||||
const toolbarColumns = computed(() => Math.max(1, navItems.value.length + (props.showDarkModeToggle ? 1 : 0)))
|
||||
const toolbarCssVars = computed(() => ({
|
||||
'--accent-color': designStore.appTheme,
|
||||
'--accent-soft-color': `${designStore.appTheme}33`,
|
||||
'gridTemplateColumns': `repeat(${toolbarColumns.value}, 1fr)`,
|
||||
}))
|
||||
|
||||
const toggleBouncing = ref(false)
|
||||
const navBounceIndex = ref<number | null>(null)
|
||||
let toggleTimer: number | null = null
|
||||
let navBounceTimer: number | null = null
|
||||
let resizeObserver: ResizeObserver | null = null
|
||||
|
||||
function setNavRef(el: Element | { $el?: Element } | null, index: number) {
|
||||
if (!el) {
|
||||
navRefs.value[index] = null
|
||||
return
|
||||
}
|
||||
const element = el instanceof HTMLElement
|
||||
? el
|
||||
: ('$el' in el ? (el.$el as HTMLElement | undefined) : undefined)
|
||||
navRefs.value[index] = element ?? null
|
||||
}
|
||||
|
||||
function updateIndicatorPosition() {
|
||||
const indicator = indicatorRef.value
|
||||
const target = navRefs.value[activeNavIndex.value]
|
||||
if (!indicator || !target) {
|
||||
return
|
||||
}
|
||||
const indicatorWidth = indicator.offsetWidth || 48
|
||||
indicatorX.value = target.offsetLeft + target.offsetWidth / 2 - indicatorWidth / 2
|
||||
}
|
||||
|
||||
function scheduleIndicatorUpdate() {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
updateIndicatorPosition()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function bindResizeObserver() {
|
||||
if (typeof ResizeObserver === 'undefined') {
|
||||
return
|
||||
}
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
scheduleIndicatorUpdate()
|
||||
})
|
||||
if (toolbarRef.value) {
|
||||
resizeObserver.observe(toolbarRef.value)
|
||||
}
|
||||
if (indicatorRef.value) {
|
||||
resizeObserver.observe(indicatorRef.value)
|
||||
}
|
||||
for (const navEl of navRefs.value) {
|
||||
if (navEl) {
|
||||
resizeObserver.observe(navEl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function goNav(path: string) {
|
||||
router.push(path)
|
||||
}
|
||||
|
||||
function handleNavClick(index: number, path: string) {
|
||||
navBounceIndex.value = null
|
||||
if (navBounceTimer) {
|
||||
window.clearTimeout(navBounceTimer)
|
||||
}
|
||||
void nextTick(() => {
|
||||
navBounceIndex.value = index
|
||||
navBounceTimer = window.setTimeout(() => {
|
||||
navBounceIndex.value = null
|
||||
}, 420)
|
||||
})
|
||||
goNav(path)
|
||||
}
|
||||
|
||||
function toggleTheme() {
|
||||
if (!props.showDarkModeToggle) {
|
||||
return
|
||||
}
|
||||
toggleBouncing.value = false
|
||||
if (toggleTimer) {
|
||||
window.clearTimeout(toggleTimer)
|
||||
}
|
||||
void nextTick(() => {
|
||||
toggleBouncing.value = true
|
||||
toggleTimer = window.setTimeout(() => {
|
||||
toggleBouncing.value = false
|
||||
}, 420)
|
||||
})
|
||||
darkModel.value = !darkModel.value
|
||||
}
|
||||
|
||||
watch(
|
||||
() => currentRoute.path,
|
||||
async () => {
|
||||
await nextTick()
|
||||
bindResizeObserver()
|
||||
scheduleIndicatorUpdate()
|
||||
},
|
||||
{ immediate: false },
|
||||
)
|
||||
|
||||
watch(activeNavIndex, async () => {
|
||||
await nextTick()
|
||||
scheduleIndicatorUpdate()
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await nextTick()
|
||||
bindResizeObserver()
|
||||
scheduleIndicatorUpdate()
|
||||
window.addEventListener('resize', scheduleIndicatorUpdate)
|
||||
const storeDark = designStore.darkMode === 'dark'
|
||||
if (isDark.value !== storeDark) {
|
||||
isDark.value = storeDark
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (toggleTimer) {
|
||||
window.clearTimeout(toggleTimer)
|
||||
}
|
||||
if (navBounceTimer) {
|
||||
window.clearTimeout(navBounceTimer)
|
||||
}
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect()
|
||||
resizeObserver = null
|
||||
}
|
||||
window.removeEventListener('resize', scheduleIndicatorUpdate as () => void)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.floating-toolbar-wrap {
|
||||
pointer-events: none;
|
||||
position: fixed;
|
||||
z-index: 20;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: calc(14px + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.floating-toolbar {
|
||||
pointer-events: auto;
|
||||
position: relative;
|
||||
width: min(92vw, 340px);
|
||||
height: 62px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
align-items: center;
|
||||
padding: 6px;
|
||||
border-radius: 31px;
|
||||
background: rgba(16, 20, 30, 0.86);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(20px) saturate(140%);
|
||||
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.floating-toolbar.dark {
|
||||
background: rgba(16, 20, 30, 0.86);
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-color: rgba(24, 39, 75, 0.12);
|
||||
box-shadow: 0 6px 16px rgba(41, 58, 88, 0.08);
|
||||
}
|
||||
|
||||
.ambient-glow {
|
||||
position: absolute;
|
||||
inset: -18px;
|
||||
background: radial-gradient(
|
||||
72% 100% at 50% 112%,
|
||||
var(--accent-soft-color),
|
||||
transparent 70%
|
||||
);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.film-grain {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.06;
|
||||
pointer-events: none;
|
||||
mix-blend-mode: soft-light;
|
||||
background-image: radial-gradient(
|
||||
circle at 22% 28%,
|
||||
rgba(255, 255, 255, 0.38) 0.35px,
|
||||
transparent 1px
|
||||
),
|
||||
radial-gradient(
|
||||
circle at 78% 72%,
|
||||
rgba(255, 255, 255, 0.26) 0.4px,
|
||||
transparent 1px
|
||||
);
|
||||
background-size:
|
||||
4px 4px,
|
||||
5px 5px;
|
||||
}
|
||||
|
||||
.active-indicator {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
width: 70px;
|
||||
height: 44px;
|
||||
margin-top: -22px;
|
||||
transition: transform 0.28s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ring-glow {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 22px;
|
||||
background: var(--accent-soft-color);
|
||||
opacity: 0.22;
|
||||
filter: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ring-clip {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 22px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.ring-spin {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 22px;
|
||||
border: 1px solid var(--accent-color);
|
||||
opacity: 0.35;
|
||||
animation: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.inner-plate {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 22px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .inner-plate {
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border: 1px solid rgba(24, 39, 75, 0.1);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8),
|
||||
0 2px 8px rgba(31, 41, 55, 0.12);
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
transition: color 0.25s ease;
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .nav-btn {
|
||||
color: rgba(44, 59, 88, 0.72);
|
||||
}
|
||||
|
||||
.nav-btn.active {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .nav-btn.active {
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.nav-btn.with-divider::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 15px;
|
||||
width: 1px;
|
||||
height: 30px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.14),
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .nav-btn.with-divider::after {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
transparent,
|
||||
rgba(36, 54, 88, 0.12),
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.theme-switch-wrap {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .toggle-btn {
|
||||
color: rgba(44, 59, 88, 0.78);
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .ring-glow {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.floating-toolbar:not(.dark) .ring-spin {
|
||||
border-color: rgba(24, 39, 75, 0.14);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.toggle-icon-wrap {
|
||||
position: relative;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.sun-icon,
|
||||
.moon-icon {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transition:
|
||||
opacity 0.28s ease,
|
||||
transform 0.32s ease;
|
||||
}
|
||||
|
||||
.sun-icon.hidden {
|
||||
opacity: 0;
|
||||
transform: rotate(90deg) scale(0.6);
|
||||
}
|
||||
|
||||
.moon-icon {
|
||||
opacity: 0;
|
||||
transform: rotate(-90deg) scale(0.6);
|
||||
}
|
||||
|
||||
.moon-icon.show {
|
||||
opacity: 1;
|
||||
transform: rotate(0deg) scale(1);
|
||||
}
|
||||
|
||||
.toggle-btn.bounce {
|
||||
animation: toggle-bounce 0.42s cubic-bezier(0.34, 1.2, 0.64, 1);
|
||||
}
|
||||
|
||||
.nav-btn.nav-bounce i {
|
||||
animation: nav-icon-bounce 0.42s cubic-bezier(0.34, 1.2, 0.64, 1);
|
||||
}
|
||||
|
||||
@keyframes toggle-bounce {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
35% {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
70% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nav-icon-bounce {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
35% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
70% {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,66 +1,58 @@
|
||||
<!-- eslint-disable prettier/prettier -->
|
||||
<template>
|
||||
<div class="h-screen flex flex-col">
|
||||
<van-nav-bar v-if="getShowHeader" placeholder fixed :title="getTitle" />
|
||||
<routerView class="flex-1 overflow-x-hidden">
|
||||
<div
|
||||
class="layout-shell h-screen flex flex-col"
|
||||
:class="{ dark: designStore.darkMode === 'dark' }"
|
||||
>
|
||||
<RouterView class="flex-1 overflow-x-hidden">
|
||||
<template #default="{ Component, route }">
|
||||
<!--
|
||||
keep-alive 标签的 include 属性是根据组件的 name 判断的,
|
||||
所以 index.vue 和 list.vue 等页面 vue 文件里一定要写上 name,
|
||||
并且与 router 路由表中使用的 name 属性 一致,否则无效
|
||||
Vue 3.3 中新引入了 defineOptions 宏声明 name 属性
|
||||
https://gist.github.com/sxzz/3995fc7251567c7c95de35f45539b9c2
|
||||
-->
|
||||
<keep-alive v-if="keepAliveComponents" :include="keepAliveComponents">
|
||||
<KeepAlive v-if="keepAliveComponents" :include="keepAliveComponents">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</KeepAlive>
|
||||
<component :is="Component" v-else :key="route.fullPath" />
|
||||
</template>
|
||||
</routerView>
|
||||
<van-tabbar route class="tabbar">
|
||||
<van-tabbar-item
|
||||
v-for="menu in getMenus"
|
||||
:key="menu.name"
|
||||
replace
|
||||
:to="menu.path"
|
||||
>
|
||||
<template #icon>
|
||||
<i :class="menu.meta?.icon" />
|
||||
</template>
|
||||
{{ menu.meta?.title }}
|
||||
</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
</RouterView>
|
||||
|
||||
<!--
|
||||
<van-tabbar route>
|
||||
<van-tabbar-item icon="home-o" to="/dashboard/index">
|
||||
首页
|
||||
</van-tabbar-item>
|
||||
<van-tabbar-item icon="search" to="/message/index">
|
||||
消息
|
||||
</van-tabbar-item>
|
||||
<van-tabbar-item icon="user-o" to="/my/index">
|
||||
我的
|
||||
</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
-->
|
||||
<FloatingNavBar :items="tabbarItems" :show-dark-mode-toggle="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import FloatingNavBar from './components/FloatingNavBar.vue'
|
||||
import { useRouteStore } from '@/store/modules/route'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
|
||||
const routeStore = useRouteStore()
|
||||
// 需要缓存的路由组件
|
||||
const designStore = useDesignSettingStore()
|
||||
|
||||
const keepAliveComponents = computed(() => routeStore.keepAliveComponents)
|
||||
const currentRoute = useRoute()
|
||||
|
||||
const getTitle = computed(() => currentRoute.meta.title as string)
|
||||
|
||||
// 菜单
|
||||
const getMenus: ComputedRef<RouteRecordRaw[]> = computed(() =>
|
||||
routeStore.menus.filter((item) => {
|
||||
return !item.meta?.innerPage
|
||||
}),
|
||||
)
|
||||
|
||||
const getShowHeader = computed(() => !currentRoute.meta.hiddenHeader)
|
||||
const tabbarItems = [
|
||||
{ label: 'Home', path: '/dashboard/index', icon: 'i-ph:house-line' },
|
||||
{ label: 'Search', path: '/message/index', icon: 'i-ph:magnifying-glass' },
|
||||
{ label: 'User', path: '/my/index', icon: 'i-ph:user-circle' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.tabbar {
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
.layout-shell {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.layout-shell.dark {
|
||||
background: #000000;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -10,7 +10,7 @@ const routeModuleList: Array<RouteRecordRaw> = [
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: '主控台',
|
||||
icon: 'i-simple-icons:atlassian',
|
||||
icon: 'i-ph:house',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@ -30,7 +30,7 @@ const routeModuleList: Array<RouteRecordRaw> = [
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: '图表',
|
||||
icon: 'i-simple-icons:soundcharts',
|
||||
icon: 'i-ph:chart-line',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@ -50,7 +50,7 @@ const routeModuleList: Array<RouteRecordRaw> = [
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: '示例',
|
||||
icon: 'i-material-symbols:award-star',
|
||||
icon: 'i-ph:code',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@ -70,7 +70,7 @@ const routeModuleList: Array<RouteRecordRaw> = [
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: '我的',
|
||||
icon: 'i-simple-icons:docsify',
|
||||
icon: 'i-ph:user',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import type { App } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPersist from 'pinia-plugin-persist'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
|
||||
const store = createPinia()
|
||||
store.use(piniaPersist)
|
||||
store.use(piniaPluginPersistedstate)
|
||||
|
||||
export function setupStore(app: App<Element>) {
|
||||
app.use(store)
|
||||
|
||||
@ -5,8 +5,7 @@ import type { DesignSettingState } from '@/settings/designSetting'
|
||||
|
||||
const { darkMode, appTheme, appThemeList, isPageAnimate, pageAnimateType } = designSetting
|
||||
|
||||
export const useDesignSettingStore = defineStore({
|
||||
id: 'app-design-setting',
|
||||
export const useDesignSettingStore = defineStore('app-design-setting', {
|
||||
state: (): DesignSettingState => ({
|
||||
darkMode,
|
||||
appTheme,
|
||||
@ -41,13 +40,8 @@ export const useDesignSettingStore = defineStore({
|
||||
},
|
||||
// 持久化
|
||||
persist: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
key: 'DESIGN-SETTING',
|
||||
storage: localStorage,
|
||||
},
|
||||
],
|
||||
key: 'DESIGN-SETTING',
|
||||
storage: localStorage,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@ -8,8 +8,7 @@ export interface IRouteState {
|
||||
keepAliveComponents: string[]
|
||||
}
|
||||
|
||||
export const useRouteStore = defineStore({
|
||||
id: 'app-route',
|
||||
export const useRouteStore = defineStore('app-route', {
|
||||
state: (): IRouteState => ({
|
||||
menus: [],
|
||||
routers: [],
|
||||
|
||||
@ -33,8 +33,7 @@ interface LoginParams {
|
||||
password: string
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
id: 'app-user',
|
||||
export const useUserStore = defineStore('app-user', {
|
||||
state: (): IUserState => ({
|
||||
userInfo: null,
|
||||
token: undefined,
|
||||
|
||||
@ -17,8 +17,8 @@ html.dark {
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #121212;
|
||||
color: var(--van-text-color) !important;
|
||||
background-color: #000000;
|
||||
color: rgba(255, 255, 255, 0.9) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,15 +93,38 @@ a:hover {
|
||||
}
|
||||
|
||||
html.light {
|
||||
body {
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.my-card {
|
||||
backdrop-filter: blur(10px);
|
||||
background: rgba(255, 255, 255, 70%);
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(24, 39, 75, 0.1);
|
||||
box-shadow: 0 4px 10px rgba(41, 58, 88, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
html.dark {
|
||||
.my-card {
|
||||
backdrop-filter: blur(10px);
|
||||
background: rgba(30, 30, 30, 70%);
|
||||
backdrop-filter: blur(12px);
|
||||
background: rgba(18, 18, 18, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.van-cell-group--inset {
|
||||
margin: 16px;
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.van-cell-group--inset .van-cell {
|
||||
background: rgba(18, 18, 18, 0.6);
|
||||
}
|
||||
|
||||
.van-cell-group .van-cell::after {
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
<template>
|
||||
<div class="h-screen flex flex-col items-center justify-center p-60px">
|
||||
<div class="wel-box w-full flex flex-col items-center justify-between">
|
||||
<Logo class="!h-30 !w-30" />
|
||||
<div class="text-darkBlue dark:text-garyWhite mb-4 mt-12 text-center text-2xl font-black">
|
||||
<div class="page-title mb-4 mt-12 text-center">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div class="mb-6 mt-4 w-full">
|
||||
@ -10,12 +9,12 @@
|
||||
<van-swipe-item
|
||||
v-for="(text, index) in getSwipeText"
|
||||
:key="index"
|
||||
class="text-center text-gray-700 leading-relaxed dark:text-gray-400"
|
||||
class="swipe-item text-center leading-relaxed"
|
||||
>
|
||||
<p class="text-lg">
|
||||
<p class="swipe-title">
|
||||
{{ text.title }}
|
||||
</p>
|
||||
<p class="text-sm">
|
||||
<p class="swipe-details">
|
||||
{{ text.details }}
|
||||
</p>
|
||||
</van-swipe-item>
|
||||
@ -28,7 +27,6 @@
|
||||
<script setup lang="ts">
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
import { useGlobSetting } from '@/hooks/setting'
|
||||
import Logo from '@/components/Logo.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'DashboardPage',
|
||||
@ -77,4 +75,56 @@ const getSwipeText = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
<style scoped lang="less">
|
||||
.page-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
html.light .page-title {
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
html.dark .page-title {
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
html.light .page-title::after,
|
||||
html.dark .page-title::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 2px;
|
||||
margin: 8px auto 0;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
v-bind('designStore.appTheme'),
|
||||
transparent
|
||||
);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.swipe-item {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
html.light .swipe-title {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
html.dark .swipe-title {
|
||||
color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
|
||||
html.light .swipe-details {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
html.dark .swipe-details {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<div class="my-4">
|
||||
<div class="example-page my-4 pb-24">
|
||||
<van-cell-group inset>
|
||||
<van-cell center title="🌓 暗黑模式">
|
||||
<template #right-icon>
|
||||
<i inline-block align-middle i="dark:carbon-moon carbon-sun" />
|
||||
<span class="ml-2">{{ isDark ? 'Dark' : 'Light' }}</span>
|
||||
<span class="mx-2">{{ isDark }}</span>
|
||||
<van-switch v-model="checked" size="22" @click="toggle()" />
|
||||
<van-switch v-model="darkSwitch" size="22" />
|
||||
</template>
|
||||
</van-cell>
|
||||
<template v-for="item in menuItems" :key="item.route">
|
||||
@ -17,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
|
||||
const designStore = useDesignSettingStore()
|
||||
@ -25,16 +24,16 @@ const designStore = useDesignSettingStore()
|
||||
const isDark = useDark({
|
||||
valueDark: 'dark',
|
||||
valueLight: 'light',
|
||||
disableTransition: false,
|
||||
})
|
||||
|
||||
const checked = ref(isDark.value)
|
||||
|
||||
const toggleDark = useToggle(isDark)
|
||||
|
||||
function toggle() {
|
||||
toggleDark()
|
||||
designStore.setDarkMode(isDark.value ? 'dark' : 'light')
|
||||
}
|
||||
const darkSwitch = computed({
|
||||
get: () => isDark.value,
|
||||
set: (value: boolean) => {
|
||||
isDark.value = value
|
||||
designStore.setDarkMode(value ? 'dark' : 'light')
|
||||
},
|
||||
})
|
||||
|
||||
const menuItems = [
|
||||
{ title: '🐗 keep-alive', route: '/editNickname' },
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="my-card m-40px rounded-2xl p-30px shadow-xl">
|
||||
<div class="my-card m-16px rounded-2xl p-24px">
|
||||
<div ref="chartRef" :style="{ height: '350px' }" />
|
||||
</div>
|
||||
</template>
|
||||
@ -7,11 +7,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import { useECharts } from '@/hooks/web/useECharts'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
|
||||
const chartRef = ref<HTMLDivElement | null>(null)
|
||||
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
||||
const designStore = useDesignSettingStore()
|
||||
|
||||
const chartColors = [designStore.appTheme, '#4a9eff', '#5dd9a8', '#ff9f7a', '#7ec8e3', '#b8a9e0']
|
||||
|
||||
const chartOptions: EChartsOption = {
|
||||
color: chartColors,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="message-page pb-24">
|
||||
<div class="section-title">
|
||||
数据概览
|
||||
</div>
|
||||
<lineChart />
|
||||
<barChart />
|
||||
<pieChart />
|
||||
@ -12,4 +15,29 @@ import barChart from './barChart.vue'
|
||||
import pieChart from './pieChart.vue'
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped lang="less">
|
||||
.section-title {
|
||||
padding: 24px 16px 16px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.15em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
html.light .section-title {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
html.dark .section-title {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
html.dark .section-title::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 1px;
|
||||
margin-top: 6px;
|
||||
background: var(--van-primary-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="my-card m-40px rounded-2xl p-30px shadow-xl">
|
||||
<div class="my-card m-16px rounded-2xl p-24px">
|
||||
<div ref="chartRef" :style="{ height: '350px' }" />
|
||||
</div>
|
||||
</template>
|
||||
@ -7,11 +7,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import { useECharts } from '@/hooks/web/useECharts'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
|
||||
const chartRef = ref<HTMLDivElement | null>(null)
|
||||
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
||||
const designStore = useDesignSettingStore()
|
||||
|
||||
const chartColors = [designStore.appTheme, '#4a9eff', '#5dd9a8', '#ff9f7a', '#7ec8e3']
|
||||
|
||||
const chartOptions: EChartsOption = {
|
||||
color: chartColors,
|
||||
title: {
|
||||
text: 'Stacked Area Chart',
|
||||
},
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="my-card m-40px rounded-2xl p-30px shadow-xl">
|
||||
<div class="my-card m-16px rounded-2xl p-24px">
|
||||
<div ref="chartRef" :style="{ height: '350px' }" />
|
||||
</div>
|
||||
</template>
|
||||
@ -7,11 +7,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import { useECharts } from '@/hooks/web/useECharts'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
|
||||
const chartRef = ref<HTMLDivElement | null>(null)
|
||||
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
||||
const designStore = useDesignSettingStore()
|
||||
|
||||
const chartColors = [designStore.appTheme, '#4a9eff', '#5dd9a8', '#ff9f7a', '#7ec8e3', '#b8a9e0']
|
||||
|
||||
const chartOptions: EChartsOption = {
|
||||
color: chartColors,
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
},
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import NavBar from './components/NavBar.vue'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
import { animates as animateOptions } from '@/settings/animateSetting'
|
||||
@ -78,15 +78,14 @@ const designStore = useDesignSettingStore()
|
||||
const isDark = useDark({
|
||||
valueDark: 'dark',
|
||||
valueLight: 'light',
|
||||
disableTransition: false,
|
||||
})
|
||||
|
||||
const toggleDark = useToggle(isDark)
|
||||
|
||||
const getDarkMode = computed({
|
||||
get: () => isDark.value,
|
||||
set: () => {
|
||||
toggleDark()
|
||||
designStore.setDarkMode(isDark.value ? 'dark' : 'light')
|
||||
set: (value: boolean) => {
|
||||
isDark.value = value
|
||||
designStore.setDarkMode(value ? 'dark' : 'light')
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="my-page">
|
||||
<div :style="getUserCoverBg" class="my-bg h-70" />
|
||||
<div
|
||||
class="my-card relative mx-6 flex flex-col items-center rounded-2xl pb-2 shadow-xl -top-18"
|
||||
class="my-card relative mx-5 flex flex-col items-center rounded-2xl pb-2 -top-18"
|
||||
>
|
||||
<van-image
|
||||
class="h-22 w-22 border-2 border-solid !absolute -top-10"
|
||||
@ -11,42 +11,42 @@
|
||||
:src="avatar"
|
||||
/>
|
||||
<div class="mt-14 flex flex-col items-center">
|
||||
<p class="mb-2 text-5 font-black">
|
||||
<p class="profile-name mb-2 text-5 font-semibold">
|
||||
{{ nickname }}
|
||||
</p>
|
||||
<p class="text-4">
|
||||
<p class="profile-sign text-4">
|
||||
{{ sign }}
|
||||
</p>
|
||||
</div>
|
||||
<van-divider class="w-full" />
|
||||
<van-divider class="profile-divider w-full" />
|
||||
|
||||
<van-cell :border="false" title="个人信息" is-link to="/editUserInfo">
|
||||
<template #icon>
|
||||
<i class="i-mingcute:idcard-fill mr-2 text-xl" />
|
||||
<i class="i-ph:user-circle mr-2 text-xl" />
|
||||
</template>
|
||||
</van-cell>
|
||||
|
||||
<van-cell :border="false" title="账号与安全" is-link to="/accountSetting">
|
||||
<template #icon>
|
||||
<i class="i-material-symbols:account-box mr-2 text-xl" />
|
||||
<i class="i-ph:shield-check mr-2 text-xl" />
|
||||
</template>
|
||||
</van-cell>
|
||||
|
||||
<van-cell :border="false" title="主题设置" is-link to="/themeSetting">
|
||||
<template #icon>
|
||||
<i class="i-material-symbols:palette mr-2 text-xl" />
|
||||
<i class="i-ph:palette mr-2 text-xl" />
|
||||
</template>
|
||||
</van-cell>
|
||||
|
||||
<van-cell :border="false" title="隐私政策" is-link>
|
||||
<template #icon>
|
||||
<i class="i-material-symbols:list-alt-rounded mr-2 text-xl" />
|
||||
<i class="i-ph:file-text mr-2 text-xl" />
|
||||
</template>
|
||||
</van-cell>
|
||||
|
||||
<van-cell :border="false" title="退出登录" is-link @click="showLogoutAction = true">
|
||||
<template #icon>
|
||||
<i class="i-solar:logout-3-bold mr-2 text-xl" />
|
||||
<i class="i-ph:sign-out mr-2 text-xl" />
|
||||
</template>
|
||||
</van-cell>
|
||||
|
||||
@ -100,10 +100,22 @@ const getUserCoverBg = computed(() => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0), #000);
|
||||
opacity: 0.9;
|
||||
opacity: 0.92;
|
||||
}
|
||||
}
|
||||
|
||||
html.dark .profile-name {
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
html.dark .profile-sign {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
html.dark .profile-divider {
|
||||
border-color: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.van-cell {
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
@ -112,4 +124,16 @@ const getUserCoverBg = computed(() => {
|
||||
background-color: var(--van-cell-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
html.dark .van-cell {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
html.dark .van-cell__right-icon {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
html.dark .van-cell:active {
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
"useDefineForClassFields": true,
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"moduleResolution": "bundler",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"#/*": ["types/*"]
|
||||
|
||||
595
types/auto-imports.d.ts
vendored
595
types/auto-imports.d.ts
vendored
@ -3,302 +3,317 @@
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const computedAsync: typeof import('@vueuse/core')['computedAsync']
|
||||
const computedEager: typeof import('@vueuse/core')['computedEager']
|
||||
const computedInject: typeof import('@vueuse/core')['computedInject']
|
||||
const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
|
||||
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
|
||||
const controlledRef: typeof import('@vueuse/core')['controlledRef']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const createEventHook: typeof import('@vueuse/core')['createEventHook']
|
||||
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
|
||||
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
|
||||
const createPinia: typeof import('pinia')['createPinia']
|
||||
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
|
||||
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
|
||||
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
|
||||
const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise']
|
||||
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
|
||||
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const defineStore: typeof import('pinia')['defineStore']
|
||||
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const extendRef: typeof import('@vueuse/core')['extendRef']
|
||||
const getActivePinia: typeof import('pinia')['getActivePinia']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const injectLocal: typeof import('@vueuse/core')['injectLocal']
|
||||
const isDefined: typeof import('@vueuse/core')['isDefined']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
|
||||
const mapActions: typeof import('pinia')['mapActions']
|
||||
const mapGetters: typeof import('pinia')['mapGetters']
|
||||
const mapState: typeof import('pinia')['mapState']
|
||||
const mapStores: typeof import('pinia')['mapStores']
|
||||
const mapWritableState: typeof import('pinia')['mapWritableState']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
|
||||
const onLongPress: typeof import('@vueuse/core')['onLongPress']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const provideLocal: typeof import('@vueuse/core')['provideLocal']
|
||||
const reactify: typeof import('@vueuse/core')['reactify']
|
||||
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
|
||||
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
|
||||
const reactivePick: typeof import('@vueuse/core')['reactivePick']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
|
||||
const refDebounced: typeof import('@vueuse/core')['refDebounced']
|
||||
const refDefault: typeof import('@vueuse/core')['refDefault']
|
||||
const refThrottled: typeof import('@vueuse/core')['refThrottled']
|
||||
const refWithControl: typeof import('@vueuse/core')['refWithControl']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const resolveRef: typeof import('@vueuse/core')['resolveRef']
|
||||
const EffectScope: typeof import('vue').EffectScope
|
||||
const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
|
||||
const asyncComputed: typeof import('@vueuse/core').asyncComputed
|
||||
const autoResetRef: typeof import('@vueuse/core').autoResetRef
|
||||
const computed: typeof import('vue').computed
|
||||
const computedAsync: typeof import('@vueuse/core').computedAsync
|
||||
const computedEager: typeof import('@vueuse/core').computedEager
|
||||
const computedInject: typeof import('@vueuse/core').computedInject
|
||||
const computedWithControl: typeof import('@vueuse/core').computedWithControl
|
||||
const controlledComputed: typeof import('@vueuse/core').controlledComputed
|
||||
const controlledRef: typeof import('@vueuse/core').controlledRef
|
||||
const createApp: typeof import('vue').createApp
|
||||
const createEventHook: typeof import('@vueuse/core').createEventHook
|
||||
const createGlobalState: typeof import('@vueuse/core').createGlobalState
|
||||
const createInjectionState: typeof import('@vueuse/core').createInjectionState
|
||||
const createPinia: typeof import('pinia').createPinia
|
||||
const createReactiveFn: typeof import('@vueuse/core').createReactiveFn
|
||||
const createRef: typeof import('@vueuse/core').createRef
|
||||
const createReusableTemplate: typeof import('@vueuse/core').createReusableTemplate
|
||||
const createSharedComposable: typeof import('@vueuse/core').createSharedComposable
|
||||
const createTemplatePromise: typeof import('@vueuse/core').createTemplatePromise
|
||||
const createUnrefFn: typeof import('@vueuse/core').createUnrefFn
|
||||
const customRef: typeof import('vue').customRef
|
||||
const debouncedRef: typeof import('@vueuse/core').debouncedRef
|
||||
const debouncedWatch: typeof import('@vueuse/core').debouncedWatch
|
||||
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
|
||||
const defineComponent: typeof import('vue').defineComponent
|
||||
const defineStore: typeof import('pinia').defineStore
|
||||
const eagerComputed: typeof import('@vueuse/core').eagerComputed
|
||||
const effectScope: typeof import('vue').effectScope
|
||||
const extendRef: typeof import('@vueuse/core').extendRef
|
||||
const getActivePinia: typeof import('pinia').getActivePinia
|
||||
const getCurrentInstance: typeof import('vue').getCurrentInstance
|
||||
const getCurrentScope: typeof import('vue').getCurrentScope
|
||||
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
|
||||
const h: typeof import('vue').h
|
||||
const ignorableWatch: typeof import('@vueuse/core').ignorableWatch
|
||||
const inject: typeof import('vue').inject
|
||||
const injectLocal: typeof import('@vueuse/core').injectLocal
|
||||
const isDefined: typeof import('@vueuse/core').isDefined
|
||||
const isProxy: typeof import('vue').isProxy
|
||||
const isReactive: typeof import('vue').isReactive
|
||||
const isReadonly: typeof import('vue').isReadonly
|
||||
const isRef: typeof import('vue').isRef
|
||||
const isShallow: typeof import('vue').isShallow
|
||||
const makeDestructurable: typeof import('@vueuse/core').makeDestructurable
|
||||
const mapActions: typeof import('pinia').mapActions
|
||||
const mapGetters: typeof import('pinia').mapGetters
|
||||
const mapState: typeof import('pinia').mapState
|
||||
const mapStores: typeof import('pinia').mapStores
|
||||
const mapWritableState: typeof import('pinia').mapWritableState
|
||||
const markRaw: typeof import('vue').markRaw
|
||||
const nextTick: typeof import('vue').nextTick
|
||||
const onActivated: typeof import('vue').onActivated
|
||||
const onBeforeMount: typeof import('vue').onBeforeMount
|
||||
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
|
||||
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
|
||||
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
|
||||
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
|
||||
const onClickOutside: typeof import('@vueuse/core').onClickOutside
|
||||
const onDeactivated: typeof import('vue').onDeactivated
|
||||
const onElementRemoval: typeof import('@vueuse/core').onElementRemoval
|
||||
const onErrorCaptured: typeof import('vue').onErrorCaptured
|
||||
const onKeyStroke: typeof import('@vueuse/core').onKeyStroke
|
||||
const onLongPress: typeof import('@vueuse/core').onLongPress
|
||||
const onMounted: typeof import('vue').onMounted
|
||||
const onRenderTracked: typeof import('vue').onRenderTracked
|
||||
const onRenderTriggered: typeof import('vue').onRenderTriggered
|
||||
const onScopeDispose: typeof import('vue').onScopeDispose
|
||||
const onServerPrefetch: typeof import('vue').onServerPrefetch
|
||||
const onStartTyping: typeof import('@vueuse/core').onStartTyping
|
||||
const onUnmounted: typeof import('vue').onUnmounted
|
||||
const onUpdated: typeof import('vue').onUpdated
|
||||
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
|
||||
const pausableWatch: typeof import('@vueuse/core').pausableWatch
|
||||
const provide: typeof import('vue').provide
|
||||
const provideLocal: typeof import('@vueuse/core').provideLocal
|
||||
const reactify: typeof import('@vueuse/core').reactify
|
||||
const reactifyObject: typeof import('@vueuse/core').reactifyObject
|
||||
const reactive: typeof import('vue').reactive
|
||||
const reactiveComputed: typeof import('@vueuse/core').reactiveComputed
|
||||
const reactiveOmit: typeof import('@vueuse/core').reactiveOmit
|
||||
const reactivePick: typeof import('@vueuse/core').reactivePick
|
||||
const readonly: typeof import('vue').readonly
|
||||
const ref: typeof import('vue').ref
|
||||
const refAutoReset: typeof import('@vueuse/core').refAutoReset
|
||||
const refDebounced: typeof import('@vueuse/core').refDebounced
|
||||
const refDefault: typeof import('@vueuse/core').refDefault
|
||||
const refManualReset: typeof import('@vueuse/core').refManualReset
|
||||
const refThrottled: typeof import('@vueuse/core').refThrottled
|
||||
const refWithControl: typeof import('@vueuse/core').refWithControl
|
||||
const resolveComponent: typeof import('vue').resolveComponent
|
||||
const resolveRef: typeof import('@vueuse/core').resolveRef
|
||||
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
||||
const setActivePinia: typeof import('pinia')['setActivePinia']
|
||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const storeToRefs: typeof import('pinia')['storeToRefs']
|
||||
const syncRef: typeof import('@vueuse/core')['syncRef']
|
||||
const syncRefs: typeof import('@vueuse/core')['syncRefs']
|
||||
const templateRef: typeof import('@vueuse/core')['templateRef']
|
||||
const throttledRef: typeof import('@vueuse/core')['throttledRef']
|
||||
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toReactive: typeof import('@vueuse/core')['toReactive']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
|
||||
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
|
||||
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
|
||||
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
|
||||
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const unrefElement: typeof import('@vueuse/core')['unrefElement']
|
||||
const until: typeof import('@vueuse/core')['until']
|
||||
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
||||
const useAnimate: typeof import('@vueuse/core')['useAnimate']
|
||||
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
|
||||
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
|
||||
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
|
||||
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
|
||||
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
|
||||
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
|
||||
const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes']
|
||||
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
|
||||
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
|
||||
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
|
||||
const useArraySome: typeof import('@vueuse/core')['useArraySome']
|
||||
const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique']
|
||||
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
|
||||
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useBase64: typeof import('@vueuse/core')['useBase64']
|
||||
const useBattery: typeof import('@vueuse/core')['useBattery']
|
||||
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
|
||||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
||||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||
const useCached: typeof import('@vueuse/core')['useCached']
|
||||
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems']
|
||||
const useCloned: typeof import('@vueuse/core')['useCloned']
|
||||
const useColorMode: typeof import('@vueuse/core')['useColorMode']
|
||||
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
|
||||
const useCounter: typeof import('@vueuse/core')['useCounter']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVar: typeof import('@vueuse/core')['useCssVar']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
|
||||
const useCycleList: typeof import('@vueuse/core')['useCycleList']
|
||||
const useDark: typeof import('@vueuse/core')['useDark']
|
||||
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
|
||||
const useDebounce: typeof import('@vueuse/core')['useDebounce']
|
||||
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
|
||||
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
|
||||
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
|
||||
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
|
||||
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
|
||||
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
|
||||
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
|
||||
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
|
||||
const useDraggable: typeof import('@vueuse/core')['useDraggable']
|
||||
const useDropZone: typeof import('@vueuse/core')['useDropZone']
|
||||
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
|
||||
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
|
||||
const useElementHover: typeof import('@vueuse/core')['useElementHover']
|
||||
const useElementSize: typeof import('@vueuse/core')['useElementSize']
|
||||
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
|
||||
const useEventBus: typeof import('@vueuse/core')['useEventBus']
|
||||
const useEventListener: typeof import('@vueuse/core')['useEventListener']
|
||||
const useEventSource: typeof import('@vueuse/core')['useEventSource']
|
||||
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
|
||||
const useFavicon: typeof import('@vueuse/core')['useFavicon']
|
||||
const useFetch: typeof import('@vueuse/core')['useFetch']
|
||||
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
|
||||
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
|
||||
const useFocus: typeof import('@vueuse/core')['useFocus']
|
||||
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
|
||||
const useFps: typeof import('@vueuse/core')['useFps']
|
||||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||
const useGamepad: typeof import('@vueuse/core')['useGamepad']
|
||||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||
const useImage: typeof import('@vueuse/core')['useImage']
|
||||
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
|
||||
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
|
||||
const useInterval: typeof import('@vueuse/core')['useInterval']
|
||||
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
|
||||
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
|
||||
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
|
||||
const useLink: typeof import('vue-router')['useLink']
|
||||
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
|
||||
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
|
||||
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
|
||||
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
|
||||
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
|
||||
const useMemoize: typeof import('@vueuse/core')['useMemoize']
|
||||
const useMemory: typeof import('@vueuse/core')['useMemory']
|
||||
const useMounted: typeof import('@vueuse/core')['useMounted']
|
||||
const useMouse: typeof import('@vueuse/core')['useMouse']
|
||||
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
|
||||
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
|
||||
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
|
||||
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
|
||||
const useNetwork: typeof import('@vueuse/core')['useNetwork']
|
||||
const useNow: typeof import('@vueuse/core')['useNow']
|
||||
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
|
||||
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
|
||||
const useOnline: typeof import('@vueuse/core')['useOnline']
|
||||
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
|
||||
const useParallax: typeof import('@vueuse/core')['useParallax']
|
||||
const useParentElement: typeof import('@vueuse/core')['useParentElement']
|
||||
const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver']
|
||||
const usePermission: typeof import('@vueuse/core')['usePermission']
|
||||
const usePointer: typeof import('@vueuse/core')['usePointer']
|
||||
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
|
||||
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
|
||||
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
|
||||
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
|
||||
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
|
||||
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
|
||||
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
|
||||
const usePrevious: typeof import('@vueuse/core')['usePrevious']
|
||||
const useRafFn: typeof import('@vueuse/core')['useRafFn']
|
||||
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
|
||||
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
|
||||
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
|
||||
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
|
||||
const useScroll: typeof import('@vueuse/core')['useScroll']
|
||||
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
|
||||
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
|
||||
const useShare: typeof import('@vueuse/core')['useShare']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useSorted: typeof import('@vueuse/core')['useSorted']
|
||||
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
|
||||
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
|
||||
const useStepper: typeof import('@vueuse/core')['useStepper']
|
||||
const useStorage: typeof import('@vueuse/core')['useStorage']
|
||||
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
|
||||
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
|
||||
const useSupported: typeof import('@vueuse/core')['useSupported']
|
||||
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
|
||||
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
|
||||
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
|
||||
const useThrottle: typeof import('@vueuse/core')['useThrottle']
|
||||
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
|
||||
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
|
||||
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
|
||||
const useTimeout: typeof import('@vueuse/core')['useTimeout']
|
||||
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
|
||||
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
|
||||
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
|
||||
const useTitle: typeof import('@vueuse/core')['useTitle']
|
||||
const useToNumber: typeof import('@vueuse/core')['useToNumber']
|
||||
const useToString: typeof import('@vueuse/core')['useToString']
|
||||
const useToggle: typeof import('@vueuse/core')['useToggle']
|
||||
const useTransition: typeof import('@vueuse/core')['useTransition']
|
||||
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
|
||||
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
|
||||
const useVModel: typeof import('@vueuse/core')['useVModel']
|
||||
const useVModels: typeof import('@vueuse/core')['useVModels']
|
||||
const useVibrate: typeof import('@vueuse/core')['useVibrate']
|
||||
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
|
||||
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
|
||||
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
|
||||
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
|
||||
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
|
||||
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
|
||||
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
|
||||
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
|
||||
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchArray: typeof import('@vueuse/core')['watchArray']
|
||||
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
|
||||
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
|
||||
const watchDeep: typeof import('@vueuse/core')['watchDeep']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
|
||||
const watchImmediate: typeof import('@vueuse/core')['watchImmediate']
|
||||
const watchOnce: typeof import('@vueuse/core')['watchOnce']
|
||||
const watchPausable: typeof import('@vueuse/core')['watchPausable']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
|
||||
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
|
||||
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
||||
const whenever: typeof import('@vueuse/core')['whenever']
|
||||
const setActivePinia: typeof import('pinia').setActivePinia
|
||||
const setMapStoreSuffix: typeof import('pinia').setMapStoreSuffix
|
||||
const shallowReactive: typeof import('vue').shallowReactive
|
||||
const shallowReadonly: typeof import('vue').shallowReadonly
|
||||
const shallowRef: typeof import('vue').shallowRef
|
||||
const storeToRefs: typeof import('pinia').storeToRefs
|
||||
const syncRef: typeof import('@vueuse/core').syncRef
|
||||
const syncRefs: typeof import('@vueuse/core').syncRefs
|
||||
const templateRef: typeof import('@vueuse/core').templateRef
|
||||
const throttledRef: typeof import('@vueuse/core').throttledRef
|
||||
const throttledWatch: typeof import('@vueuse/core').throttledWatch
|
||||
const toRaw: typeof import('vue').toRaw
|
||||
const toReactive: typeof import('@vueuse/core').toReactive
|
||||
const toRef: typeof import('vue').toRef
|
||||
const toRefs: typeof import('vue').toRefs
|
||||
const toValue: typeof import('vue').toValue
|
||||
const triggerRef: typeof import('vue').triggerRef
|
||||
const tryOnBeforeMount: typeof import('@vueuse/core').tryOnBeforeMount
|
||||
const tryOnBeforeUnmount: typeof import('@vueuse/core').tryOnBeforeUnmount
|
||||
const tryOnMounted: typeof import('@vueuse/core').tryOnMounted
|
||||
const tryOnScopeDispose: typeof import('@vueuse/core').tryOnScopeDispose
|
||||
const tryOnUnmounted: typeof import('@vueuse/core').tryOnUnmounted
|
||||
const unref: typeof import('vue').unref
|
||||
const unrefElement: typeof import('@vueuse/core').unrefElement
|
||||
const until: typeof import('@vueuse/core').until
|
||||
const useActiveElement: typeof import('@vueuse/core').useActiveElement
|
||||
const useAnimate: typeof import('@vueuse/core').useAnimate
|
||||
const useArrayDifference: typeof import('@vueuse/core').useArrayDifference
|
||||
const useArrayEvery: typeof import('@vueuse/core').useArrayEvery
|
||||
const useArrayFilter: typeof import('@vueuse/core').useArrayFilter
|
||||
const useArrayFind: typeof import('@vueuse/core').useArrayFind
|
||||
const useArrayFindIndex: typeof import('@vueuse/core').useArrayFindIndex
|
||||
const useArrayFindLast: typeof import('@vueuse/core').useArrayFindLast
|
||||
const useArrayIncludes: typeof import('@vueuse/core').useArrayIncludes
|
||||
const useArrayJoin: typeof import('@vueuse/core').useArrayJoin
|
||||
const useArrayMap: typeof import('@vueuse/core').useArrayMap
|
||||
const useArrayReduce: typeof import('@vueuse/core').useArrayReduce
|
||||
const useArraySome: typeof import('@vueuse/core').useArraySome
|
||||
const useArrayUnique: typeof import('@vueuse/core').useArrayUnique
|
||||
const useAsyncQueue: typeof import('@vueuse/core').useAsyncQueue
|
||||
const useAsyncState: typeof import('@vueuse/core').useAsyncState
|
||||
const useAttrs: typeof import('vue').useAttrs
|
||||
const useBase64: typeof import('@vueuse/core').useBase64
|
||||
const useBattery: typeof import('@vueuse/core').useBattery
|
||||
const useBluetooth: typeof import('@vueuse/core').useBluetooth
|
||||
const useBreakpoints: typeof import('@vueuse/core').useBreakpoints
|
||||
const useBroadcastChannel: typeof import('@vueuse/core').useBroadcastChannel
|
||||
const useBrowserLocation: typeof import('@vueuse/core').useBrowserLocation
|
||||
const useCached: typeof import('@vueuse/core').useCached
|
||||
const useClipboard: typeof import('@vueuse/core').useClipboard
|
||||
const useClipboardItems: typeof import('@vueuse/core').useClipboardItems
|
||||
const useCloned: typeof import('@vueuse/core').useCloned
|
||||
const useColorMode: typeof import('@vueuse/core').useColorMode
|
||||
const useConfirmDialog: typeof import('@vueuse/core').useConfirmDialog
|
||||
const useCountdown: typeof import('@vueuse/core').useCountdown
|
||||
const useCounter: typeof import('@vueuse/core').useCounter
|
||||
const useCssModule: typeof import('vue').useCssModule
|
||||
const useCssSupports: typeof import('@vueuse/core').useCssSupports
|
||||
const useCssVar: typeof import('@vueuse/core').useCssVar
|
||||
const useCssVars: typeof import('vue').useCssVars
|
||||
const useCurrentElement: typeof import('@vueuse/core').useCurrentElement
|
||||
const useCycleList: typeof import('@vueuse/core').useCycleList
|
||||
const useDark: typeof import('@vueuse/core').useDark
|
||||
const useDateFormat: typeof import('@vueuse/core').useDateFormat
|
||||
const useDebounce: typeof import('@vueuse/core').useDebounce
|
||||
const useDebounceFn: typeof import('@vueuse/core').useDebounceFn
|
||||
const useDebouncedRefHistory: typeof import('@vueuse/core').useDebouncedRefHistory
|
||||
const useDeviceMotion: typeof import('@vueuse/core').useDeviceMotion
|
||||
const useDeviceOrientation: typeof import('@vueuse/core').useDeviceOrientation
|
||||
const useDevicePixelRatio: typeof import('@vueuse/core').useDevicePixelRatio
|
||||
const useDevicesList: typeof import('@vueuse/core').useDevicesList
|
||||
const useDisplayMedia: typeof import('@vueuse/core').useDisplayMedia
|
||||
const useDocumentVisibility: typeof import('@vueuse/core').useDocumentVisibility
|
||||
const useDraggable: typeof import('@vueuse/core').useDraggable
|
||||
const useDropZone: typeof import('@vueuse/core').useDropZone
|
||||
const useElementBounding: typeof import('@vueuse/core').useElementBounding
|
||||
const useElementByPoint: typeof import('@vueuse/core').useElementByPoint
|
||||
const useElementHover: typeof import('@vueuse/core').useElementHover
|
||||
const useElementSize: typeof import('@vueuse/core').useElementSize
|
||||
const useElementVisibility: typeof import('@vueuse/core').useElementVisibility
|
||||
const useEventBus: typeof import('@vueuse/core').useEventBus
|
||||
const useEventListener: typeof import('@vueuse/core').useEventListener
|
||||
const useEventSource: typeof import('@vueuse/core').useEventSource
|
||||
const useEyeDropper: typeof import('@vueuse/core').useEyeDropper
|
||||
const useFavicon: typeof import('@vueuse/core').useFavicon
|
||||
const useFetch: typeof import('@vueuse/core').useFetch
|
||||
const useFileDialog: typeof import('@vueuse/core').useFileDialog
|
||||
const useFileSystemAccess: typeof import('@vueuse/core').useFileSystemAccess
|
||||
const useFocus: typeof import('@vueuse/core').useFocus
|
||||
const useFocusWithin: typeof import('@vueuse/core').useFocusWithin
|
||||
const useFps: typeof import('@vueuse/core').useFps
|
||||
const useFullscreen: typeof import('@vueuse/core').useFullscreen
|
||||
const useGamepad: typeof import('@vueuse/core').useGamepad
|
||||
const useGeolocation: typeof import('@vueuse/core').useGeolocation
|
||||
const useId: typeof import('vue').useId
|
||||
const useIdle: typeof import('@vueuse/core').useIdle
|
||||
const useImage: typeof import('@vueuse/core').useImage
|
||||
const useInfiniteScroll: typeof import('@vueuse/core').useInfiniteScroll
|
||||
const useIntersectionObserver: typeof import('@vueuse/core').useIntersectionObserver
|
||||
const useInterval: typeof import('@vueuse/core').useInterval
|
||||
const useIntervalFn: typeof import('@vueuse/core').useIntervalFn
|
||||
const useKeyModifier: typeof import('@vueuse/core').useKeyModifier
|
||||
const useLastChanged: typeof import('@vueuse/core').useLastChanged
|
||||
const useLink: typeof import('vue-router').useLink
|
||||
const useLocalStorage: typeof import('@vueuse/core').useLocalStorage
|
||||
const useMagicKeys: typeof import('@vueuse/core').useMagicKeys
|
||||
const useManualRefHistory: typeof import('@vueuse/core').useManualRefHistory
|
||||
const useMediaControls: typeof import('@vueuse/core').useMediaControls
|
||||
const useMediaQuery: typeof import('@vueuse/core').useMediaQuery
|
||||
const useMemoize: typeof import('@vueuse/core').useMemoize
|
||||
const useMemory: typeof import('@vueuse/core').useMemory
|
||||
const useModel: typeof import('vue').useModel
|
||||
const useMounted: typeof import('@vueuse/core').useMounted
|
||||
const useMouse: typeof import('@vueuse/core').useMouse
|
||||
const useMouseInElement: typeof import('@vueuse/core').useMouseInElement
|
||||
const useMousePressed: typeof import('@vueuse/core').useMousePressed
|
||||
const useMutationObserver: typeof import('@vueuse/core').useMutationObserver
|
||||
const useNavigatorLanguage: typeof import('@vueuse/core').useNavigatorLanguage
|
||||
const useNetwork: typeof import('@vueuse/core').useNetwork
|
||||
const useNow: typeof import('@vueuse/core').useNow
|
||||
const useObjectUrl: typeof import('@vueuse/core').useObjectUrl
|
||||
const useOffsetPagination: typeof import('@vueuse/core').useOffsetPagination
|
||||
const useOnline: typeof import('@vueuse/core').useOnline
|
||||
const usePageLeave: typeof import('@vueuse/core').usePageLeave
|
||||
const useParallax: typeof import('@vueuse/core').useParallax
|
||||
const useParentElement: typeof import('@vueuse/core').useParentElement
|
||||
const usePerformanceObserver: typeof import('@vueuse/core').usePerformanceObserver
|
||||
const usePermission: typeof import('@vueuse/core').usePermission
|
||||
const usePointer: typeof import('@vueuse/core').usePointer
|
||||
const usePointerLock: typeof import('@vueuse/core').usePointerLock
|
||||
const usePointerSwipe: typeof import('@vueuse/core').usePointerSwipe
|
||||
const usePreferredColorScheme: typeof import('@vueuse/core').usePreferredColorScheme
|
||||
const usePreferredContrast: typeof import('@vueuse/core').usePreferredContrast
|
||||
const usePreferredDark: typeof import('@vueuse/core').usePreferredDark
|
||||
const usePreferredLanguages: typeof import('@vueuse/core').usePreferredLanguages
|
||||
const usePreferredReducedMotion: typeof import('@vueuse/core').usePreferredReducedMotion
|
||||
const usePreferredReducedTransparency: typeof import('@vueuse/core').usePreferredReducedTransparency
|
||||
const usePrevious: typeof import('@vueuse/core').usePrevious
|
||||
const useRafFn: typeof import('@vueuse/core').useRafFn
|
||||
const useRefHistory: typeof import('@vueuse/core').useRefHistory
|
||||
const useResizeObserver: typeof import('@vueuse/core').useResizeObserver
|
||||
const useRoute: typeof import('vue-router').useRoute
|
||||
const useRouter: typeof import('vue-router').useRouter
|
||||
const useSSRWidth: typeof import('@vueuse/core').useSSRWidth
|
||||
const useScreenOrientation: typeof import('@vueuse/core').useScreenOrientation
|
||||
const useScreenSafeArea: typeof import('@vueuse/core').useScreenSafeArea
|
||||
const useScriptTag: typeof import('@vueuse/core').useScriptTag
|
||||
const useScroll: typeof import('@vueuse/core').useScroll
|
||||
const useScrollLock: typeof import('@vueuse/core').useScrollLock
|
||||
const useSessionStorage: typeof import('@vueuse/core').useSessionStorage
|
||||
const useShare: typeof import('@vueuse/core').useShare
|
||||
const useSlots: typeof import('vue').useSlots
|
||||
const useSorted: typeof import('@vueuse/core').useSorted
|
||||
const useSpeechRecognition: typeof import('@vueuse/core').useSpeechRecognition
|
||||
const useSpeechSynthesis: typeof import('@vueuse/core').useSpeechSynthesis
|
||||
const useStepper: typeof import('@vueuse/core').useStepper
|
||||
const useStorage: typeof import('@vueuse/core').useStorage
|
||||
const useStorageAsync: typeof import('@vueuse/core').useStorageAsync
|
||||
const useStyleTag: typeof import('@vueuse/core').useStyleTag
|
||||
const useSupported: typeof import('@vueuse/core').useSupported
|
||||
const useSwipe: typeof import('@vueuse/core').useSwipe
|
||||
const useTemplateRef: typeof import('vue').useTemplateRef
|
||||
const useTemplateRefsList: typeof import('@vueuse/core').useTemplateRefsList
|
||||
const useTextDirection: typeof import('@vueuse/core').useTextDirection
|
||||
const useTextSelection: typeof import('@vueuse/core').useTextSelection
|
||||
const useTextareaAutosize: typeof import('@vueuse/core').useTextareaAutosize
|
||||
const useThrottle: typeof import('@vueuse/core').useThrottle
|
||||
const useThrottleFn: typeof import('@vueuse/core').useThrottleFn
|
||||
const useThrottledRefHistory: typeof import('@vueuse/core').useThrottledRefHistory
|
||||
const useTimeAgo: typeof import('@vueuse/core').useTimeAgo
|
||||
const useTimeAgoIntl: typeof import('@vueuse/core').useTimeAgoIntl
|
||||
const useTimeout: typeof import('@vueuse/core').useTimeout
|
||||
const useTimeoutFn: typeof import('@vueuse/core').useTimeoutFn
|
||||
const useTimeoutPoll: typeof import('@vueuse/core').useTimeoutPoll
|
||||
const useTimestamp: typeof import('@vueuse/core').useTimestamp
|
||||
const useTitle: typeof import('@vueuse/core').useTitle
|
||||
const useToNumber: typeof import('@vueuse/core').useToNumber
|
||||
const useToString: typeof import('@vueuse/core').useToString
|
||||
const useToggle: typeof import('@vueuse/core').useToggle
|
||||
const useTransition: typeof import('@vueuse/core').useTransition
|
||||
const useUrlSearchParams: typeof import('@vueuse/core').useUrlSearchParams
|
||||
const useUserMedia: typeof import('@vueuse/core').useUserMedia
|
||||
const useVModel: typeof import('@vueuse/core').useVModel
|
||||
const useVModels: typeof import('@vueuse/core').useVModels
|
||||
const useVibrate: typeof import('@vueuse/core').useVibrate
|
||||
const useVirtualList: typeof import('@vueuse/core').useVirtualList
|
||||
const useWakeLock: typeof import('@vueuse/core').useWakeLock
|
||||
const useWebNotification: typeof import('@vueuse/core').useWebNotification
|
||||
const useWebSocket: typeof import('@vueuse/core').useWebSocket
|
||||
const useWebWorker: typeof import('@vueuse/core').useWebWorker
|
||||
const useWebWorkerFn: typeof import('@vueuse/core').useWebWorkerFn
|
||||
const useWindowFocus: typeof import('@vueuse/core').useWindowFocus
|
||||
const useWindowScroll: typeof import('@vueuse/core').useWindowScroll
|
||||
const useWindowSize: typeof import('@vueuse/core').useWindowSize
|
||||
const watch: typeof import('vue').watch
|
||||
const watchArray: typeof import('@vueuse/core').watchArray
|
||||
const watchAtMost: typeof import('@vueuse/core').watchAtMost
|
||||
const watchDebounced: typeof import('@vueuse/core').watchDebounced
|
||||
const watchDeep: typeof import('@vueuse/core').watchDeep
|
||||
const watchEffect: typeof import('vue').watchEffect
|
||||
const watchIgnorable: typeof import('@vueuse/core').watchIgnorable
|
||||
const watchImmediate: typeof import('@vueuse/core').watchImmediate
|
||||
const watchOnce: typeof import('@vueuse/core').watchOnce
|
||||
const watchPausable: typeof import('@vueuse/core').watchPausable
|
||||
const watchPostEffect: typeof import('vue').watchPostEffect
|
||||
const watchSyncEffect: typeof import('vue').watchSyncEffect
|
||||
const watchThrottled: typeof import('@vueuse/core').watchThrottled
|
||||
const watchTriggerable: typeof import('@vueuse/core').watchTriggerable
|
||||
const watchWithFilter: typeof import('@vueuse/core').watchWithFilter
|
||||
const whenever: typeof import('@vueuse/core').whenever
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
||||
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
|
||||
@ -75,9 +75,9 @@ export default defineConfig({
|
||||
// 因此无法生成对应的 CSS。为了解决这个问题,你可以使用 UnoCSS 的 safelist 选项来指定一些始终需要生成的 CSS 类。
|
||||
// https://unocss.dev/guide/advanced#safelist
|
||||
safelist: [
|
||||
'i-simple-icons:atlassian',
|
||||
'i-simple-icons:soundcharts',
|
||||
'i-simple-icons:docsify',
|
||||
'i-material-symbols:award-star',
|
||||
'i-ph:house',
|
||||
'i-ph:chart-line',
|
||||
'i-ph:code',
|
||||
'i-ph:user',
|
||||
],
|
||||
})
|
||||
|
||||
@ -69,16 +69,17 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||
},
|
||||
|
||||
esbuild: {
|
||||
// 使用 esbuild 压缩 剔除 console.log
|
||||
drop: VITE_DROP_CONSOLE ? ['debugger', 'console'] : [],
|
||||
// minify: true, // minify: true, 等于 minify: 'esbuild',
|
||||
},
|
||||
|
||||
build: {
|
||||
// 设置最终构建的浏览器兼容目标
|
||||
target: 'es2015',
|
||||
minify: 'esbuild',
|
||||
// Vite 8 的 oxc 不支持 drop 选项,按需切换到 terser 去除 console/debugger
|
||||
minify: VITE_DROP_CONSOLE ? 'terser' : 'oxc',
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: VITE_DROP_CONSOLE,
|
||||
drop_debugger: VITE_DROP_CONSOLE,
|
||||
},
|
||||
},
|
||||
// 构建后是否生成 source map 文件(用于线上报错代码报错映射对应代码)
|
||||
sourcemap: false,
|
||||
cssTarget: 'chrome80',
|
||||
@ -98,8 +99,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||
reportCompressedSize: true,
|
||||
// chunk 大小警告的限制(以 kbs 为单位)
|
||||
chunkSizeWarningLimit: 2000,
|
||||
// 自定义底层的 Rollup 打包配置
|
||||
rollupOptions: {
|
||||
// 自定义底层的 Rolldown 打包配置
|
||||
rolldownOptions: {
|
||||
// 静态资源分类打包
|
||||
output: {
|
||||
chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user