refactor(projects): 重构browser tab初步

This commit is contained in:
Soybean 2021-09-23 19:47:40 +08:00
parent 22f8f3f014
commit 51b8603545
10 changed files with 370 additions and 206 deletions

View File

@ -47,7 +47,7 @@
"@vicons/material": "^0.11.0",
"@vicons/tabler": "^0.11.0",
"@vitejs/plugin-vue": "^1.9.0",
"@vue/compiler-sfc": "^3.2.13",
"@vue/compiler-sfc": "^3.2.14",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"commitizen": "^4.2.4",

View File

@ -18,7 +18,7 @@ specifiers:
'@vicons/material': ^0.11.0
'@vicons/tabler': ^0.11.0
'@vitejs/plugin-vue': ^1.9.0
'@vue/compiler-sfc': ^3.2.13
'@vue/compiler-sfc': ^3.2.14
'@vue/eslint-config-prettier': ^6.0.0
'@vue/eslint-config-typescript': ^7.0.0
'@vueuse/core': ^6.4.1
@ -87,7 +87,7 @@ devDependencies:
'@vicons/material': registry.nlark.com/@vicons/material/0.11.0
'@vicons/tabler': registry.nlark.com/@vicons/tabler/0.11.0
'@vitejs/plugin-vue': registry.nlark.com/@vitejs/plugin-vue/1.9.0_vite@2.5.10
'@vue/compiler-sfc': registry.nlark.com/@vue/compiler-sfc/3.2.13
'@vue/compiler-sfc': registry.npmmirror.com/@vue/compiler-sfc/3.2.14
'@vue/eslint-config-prettier': 6.0.0_07ea7830c059e0b322b8e6cb8d02712b
'@vue/eslint-config-typescript': 7.0.0_6206e63df2a67a196202627e217b5893
commitizen: registry.nlark.com/commitizen/4.2.4
@ -107,7 +107,7 @@ devDependencies:
prettier: registry.nlark.com/prettier/2.4.1
sass: registry.nlark.com/sass/1.42.1
typescript: registry.nlark.com/typescript/4.4.3
unplugin-icons: registry.nlark.com/unplugin-icons/0.11.1_847ba6615f49396ffc506f8fe9918fc7
unplugin-icons: registry.nlark.com/unplugin-icons/0.11.1_693bf1c79fbffb1e53bf4a7d956fe1c1
unplugin-vue-components: registry.npmmirror.com/unplugin-vue-components/0.15.2_vite@2.5.10+vue@3.2.10
vite: registry.nlark.com/vite/2.5.10
vite-plugin-html: registry.nlark.com/vite-plugin-html/2.1.0_vite@2.5.10
@ -1745,7 +1745,7 @@ packages:
hasBin: true
registry.nlark.com/@babel/parser/7.15.6:
resolution: {integrity: sha1-BDuao8MDwHIuU3f++Rl/TPF5ZUk=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@babel/parser/download/@babel/parser-7.15.6.tgz}
resolution: {integrity: sha1-BDuao8MDwHIuU3f++Rl/TPF5ZUk=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@babel/parser/download/@babel/parser-7.15.6.tgz}
name: '@babel/parser'
version: 7.15.6
engines: {node: '>=6.0.0'}
@ -2217,6 +2217,10 @@ packages:
peerDependencies:
'@typescript-eslint/parser': ^4.0.0
eslint: ^5.0.0 || ^6.0.0 || ^7.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/experimental-utils': registry.nlark.com/@typescript-eslint/experimental-utils/4.31.2_eslint@7.32.0+typescript@4.4.3
'@typescript-eslint/parser': registry.nlark.com/@typescript-eslint/parser/4.31.2_eslint@7.32.0+typescript@4.4.3
@ -2227,9 +2231,9 @@ packages:
regexpp: registry.nlark.com/regexpp/3.2.0
semver: registry.nlark.com/semver/7.3.5
tsutils: registry.nlark.com/tsutils/3.21.0_typescript@4.4.3
typescript: registry.nlark.com/typescript/4.4.3
transitivePeerDependencies:
- supports-color
- typescript
dev: true
registry.nlark.com/@typescript-eslint/experimental-utils/4.31.2_eslint@7.32.0+typescript@4.4.3:
@ -2261,15 +2265,19 @@ packages:
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
eslint: ^5.0.0 || ^6.0.0 || ^7.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': registry.nlark.com/@typescript-eslint/scope-manager/4.31.2
'@typescript-eslint/types': registry.nlark.com/@typescript-eslint/types/4.31.2
'@typescript-eslint/typescript-estree': registry.nlark.com/@typescript-eslint/typescript-estree/4.31.2_typescript@4.4.3
debug: registry.nlark.com/debug/4.3.2
eslint: registry.nlark.com/eslint/7.32.0
typescript: registry.nlark.com/typescript/4.4.3
transitivePeerDependencies:
- supports-color
- typescript
dev: true
registry.nlark.com/@typescript-eslint/scope-manager/4.31.2:
@ -2295,6 +2303,11 @@ packages:
name: '@typescript-eslint/typescript-estree'
version: 4.31.2
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': registry.nlark.com/@typescript-eslint/types/4.31.2
'@typescript-eslint/visitor-keys': registry.nlark.com/@typescript-eslint/visitor-keys/4.31.2
@ -2303,9 +2316,9 @@ packages:
is-glob: registry.nlark.com/is-glob/4.0.1
semver: registry.nlark.com/semver/7.3.5
tsutils: registry.nlark.com/tsutils/3.21.0_typescript@4.4.3
typescript: registry.nlark.com/typescript/4.4.3
transitivePeerDependencies:
- supports-color
- typescript
dev: true
registry.nlark.com/@typescript-eslint/visitor-keys/4.31.2:
@ -2462,17 +2475,6 @@ packages:
source-map: registry.nlark.com/source-map/0.6.1
dev: true
registry.nlark.com/@vue/compiler-core/3.2.13:
resolution: {integrity: sha1-kBJoCIuYpTxDvg8Cv6Djo4mta/Q=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/compiler-core/download/@vue/compiler-core-3.2.13.tgz}
name: '@vue/compiler-core'
version: 3.2.13
dependencies:
'@babel/parser': registry.nlark.com/@babel/parser/7.15.6
'@vue/shared': registry.nlark.com/@vue/shared/3.2.13
estree-walker: registry.nlark.com/estree-walker/2.0.2
source-map: registry.nlark.com/source-map/0.6.1
dev: true
registry.nlark.com/@vue/compiler-dom/3.2.10:
resolution: {integrity: sha1-GzQuOnkwyZFWlF5t7yer5nGmp2o=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/compiler-dom/download/@vue/compiler-dom-3.2.10.tgz}
name: '@vue/compiler-dom'
@ -2491,41 +2493,6 @@ packages:
'@vue/shared': registry.nlark.com/@vue/shared/3.2.11
dev: true
registry.nlark.com/@vue/compiler-dom/3.2.13:
resolution: {integrity: sha1-AomCSU+52XgH1SdbQjVXMmhvjtc=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/compiler-dom/download/@vue/compiler-dom-3.2.13.tgz}
name: '@vue/compiler-dom'
version: 3.2.13
dependencies:
'@vue/compiler-core': registry.nlark.com/@vue/compiler-core/3.2.13
'@vue/shared': registry.nlark.com/@vue/shared/3.2.13
dev: true
registry.nlark.com/@vue/compiler-sfc/3.2.13:
resolution: {integrity: sha1-o4R1BIqtnJbPBN/mNRKbQX4PkpU=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/compiler-sfc/download/@vue/compiler-sfc-3.2.13.tgz}
name: '@vue/compiler-sfc'
version: 3.2.13
dependencies:
'@babel/parser': registry.nlark.com/@babel/parser/7.15.6
'@vue/compiler-core': registry.nlark.com/@vue/compiler-core/3.2.13
'@vue/compiler-dom': registry.nlark.com/@vue/compiler-dom/3.2.13
'@vue/compiler-ssr': registry.nlark.com/@vue/compiler-ssr/3.2.13
'@vue/ref-transform': registry.nlark.com/@vue/ref-transform/3.2.13
'@vue/shared': registry.nlark.com/@vue/shared/3.2.13
estree-walker: registry.nlark.com/estree-walker/2.0.2
magic-string: registry.nlark.com/magic-string/0.25.7
postcss: registry.nlark.com/postcss/8.3.6
source-map: registry.nlark.com/source-map/0.6.1
dev: true
registry.nlark.com/@vue/compiler-ssr/3.2.13:
resolution: {integrity: sha1-mENGcuC0iMKv+ksFcHMda+XNoYc=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/compiler-ssr/download/@vue/compiler-ssr-3.2.13.tgz}
name: '@vue/compiler-ssr'
version: 3.2.13
dependencies:
'@vue/compiler-dom': registry.nlark.com/@vue/compiler-dom/3.2.13
'@vue/shared': registry.nlark.com/@vue/shared/3.2.13
dev: true
registry.nlark.com/@vue/devtools-api/6.0.0-beta.15:
resolution: {integrity: sha1-rXyzhOBi8WW8+cg3MhJb/7wq2D0=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/devtools-api/download/@vue/devtools-api-6.0.0-beta.15.tgz}
name: '@vue/devtools-api'
@ -2548,18 +2515,6 @@ packages:
'@vue/shared': registry.nlark.com/@vue/shared/3.2.11
dev: true
registry.nlark.com/@vue/ref-transform/3.2.13:
resolution: {integrity: sha1-at/OUNOIzANoPZ0rpY86O95RZvQ=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/ref-transform/download/@vue/ref-transform-3.2.13.tgz}
name: '@vue/ref-transform'
version: 3.2.13
dependencies:
'@babel/parser': registry.nlark.com/@babel/parser/7.15.6
'@vue/compiler-core': registry.nlark.com/@vue/compiler-core/3.2.13
'@vue/shared': registry.nlark.com/@vue/shared/3.2.13
estree-walker: registry.nlark.com/estree-walker/2.0.2
magic-string: registry.nlark.com/magic-string/0.25.7
dev: true
registry.nlark.com/@vue/runtime-core/3.2.10:
resolution: {integrity: sha1-XDWzJnWa96iImS/tFGMJNFw/3RM=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/runtime-core/download/@vue/runtime-core-3.2.10.tgz}
name: '@vue/runtime-core'
@ -2591,12 +2546,6 @@ packages:
version: 3.2.11
dev: true
registry.nlark.com/@vue/shared/3.2.13:
resolution: {integrity: sha1-yDDvlm168SWY4OqGKlVpXqWJzUc=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.13.tgz}
name: '@vue/shared'
version: 3.2.13
dev: true
registry.nlark.com/@vueuse/core/6.4.1_vue@3.2.10:
resolution: {integrity: sha1-IUFpl6I7+0kkpQgu1vqVkCf4DQQ=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@vueuse/core/download/@vueuse/core-6.4.1.tgz}
id: registry.nlark.com/@vueuse/core/6.4.1
@ -3605,7 +3554,7 @@ packages:
dev: true
registry.nlark.com/estree-walker/2.0.2:
resolution: {integrity: sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/estree-walker/download/estree-walker-2.0.2.tgz}
resolution: {integrity: sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/estree-walker/download/estree-walker-2.0.2.tgz}
name: estree-walker
version: 2.0.2
dev: true
@ -4522,7 +4471,7 @@ packages:
dev: false
registry.nlark.com/nanoid/3.1.25:
resolution: {integrity: sha1-CcoydHwOVD8OGBS303k0d/nI4VI=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/nanoid/download/nanoid-3.1.25.tgz}
resolution: {integrity: sha1-CcoydHwOVD8OGBS303k0d/nI4VI=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/nanoid/download/nanoid-3.1.25.tgz}
name: nanoid
version: 3.1.25
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -4792,6 +4741,9 @@ packages:
engines: {node: '>= 10'}
peerDependencies:
ts-node: '>=9.0.0'
peerDependenciesMeta:
ts-node:
optional: true
dependencies:
import-cwd: registry.nlark.com/import-cwd/3.0.0
lilconfig: registry.nlark.com/lilconfig/2.0.3
@ -4799,12 +4751,12 @@ packages:
dev: true
registry.nlark.com/postcss/8.3.6:
resolution: {integrity: sha1-JzDddql5afN/U7mmCWGXvjEcxOo=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/postcss/download/postcss-8.3.6.tgz?cache=0&sync_timestamp=1632290659105&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpostcss%2Fdownload%2Fpostcss-8.3.6.tgz}
resolution: {integrity: sha1-JzDddql5afN/U7mmCWGXvjEcxOo=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/postcss/download/postcss-8.3.6.tgz?cache=0&sync_timestamp=1632290659105&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpostcss%2Fdownload%2Fpostcss-8.3.6.tgz}
name: postcss
version: 8.3.6
engines: {node: ^10 || ^12 || >=14}
dependencies:
colorette: registry.nlark.com/colorette/1.3.0
colorette: registry.npmmirror.com/colorette/1.3.0
nanoid: registry.nlark.com/nanoid/3.1.25
source-map-js: registry.nlark.com/source-map-js/0.6.2
dev: true
@ -5156,14 +5108,14 @@ packages:
dev: true
registry.nlark.com/source-map-js/0.6.2:
resolution: {integrity: sha1-C7XeYxtBz72mz7qL0FqA79/SOF4=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/source-map-js/download/source-map-js-0.6.2.tgz}
resolution: {integrity: sha1-C7XeYxtBz72mz7qL0FqA79/SOF4=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/source-map-js/download/source-map-js-0.6.2.tgz}
name: source-map-js
version: 0.6.2
engines: {node: '>=0.10.0'}
dev: true
registry.nlark.com/source-map/0.6.1:
resolution: {integrity: sha1-dHIq8y6WFOnCh6jQu95IteLxomM=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/source-map/download/source-map-0.6.1.tgz}
resolution: {integrity: sha1-dHIq8y6WFOnCh6jQu95IteLxomM=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/source-map/download/source-map-0.6.1.tgz}
name: source-map
version: 0.6.1
engines: {node: '>=0.10.0'}
@ -5383,6 +5335,9 @@ packages:
hasBin: true
peerDependencies:
typescript: ^4.2.3
peerDependenciesMeta:
typescript:
optional: true
dependencies:
cac: registry.nlark.com/cac/6.7.3
chalk: registry.nlark.com/chalk/4.1.2
@ -5468,7 +5423,7 @@ packages:
hasBin: true
dev: true
registry.nlark.com/unplugin-icons/0.11.1_847ba6615f49396ffc506f8fe9918fc7:
registry.nlark.com/unplugin-icons/0.11.1_693bf1c79fbffb1e53bf4a7d956fe1c1:
resolution: {integrity: sha1-nodRKlzdyx0RPsD6N+xtlR/IS8U=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/unplugin-icons/download/unplugin-icons-0.11.1.tgz}
id: registry.nlark.com/unplugin-icons/0.11.1
name: unplugin-icons
@ -5492,7 +5447,7 @@ packages:
'@antfu/utils': registry.nlark.com/@antfu/utils/0.3.0
'@iconify/json': registry.nlark.com/@iconify/json/1.1.405
'@iconify/json-tools': registry.nlark.com/@iconify/json-tools/1.0.10
'@vue/compiler-sfc': registry.nlark.com/@vue/compiler-sfc/3.2.13
'@vue/compiler-sfc': registry.npmmirror.com/@vue/compiler-sfc/3.2.14
has-pkg: registry.nlark.com/has-pkg/0.0.1
unplugin: registry.nlark.com/unplugin/0.2.9_vite@2.5.10
transitivePeerDependencies:
@ -5510,6 +5465,13 @@ packages:
rollup: ^2.50.0
vite: ^2.3.0
webpack: 4 || 5
peerDependenciesMeta:
rollup:
optional: true
vite:
optional: true
webpack:
optional: true
dependencies:
upath: registry.nlark.com/upath/2.0.1
vite: registry.nlark.com/vite/2.5.10
@ -5964,6 +5926,76 @@ packages:
engines: {node: '>=10'}
dev: true
registry.npmmirror.com/@vue/compiler-core/3.2.14:
resolution: {integrity: sha1-CTv1cu4qbH7es6FbEwG5EDde5Pw=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-core/download/@vue/compiler-core-3.2.14.tgz}
name: '@vue/compiler-core'
version: 3.2.14
dependencies:
'@babel/parser': registry.nlark.com/@babel/parser/7.15.6
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.14
estree-walker: registry.nlark.com/estree-walker/2.0.2
source-map: registry.nlark.com/source-map/0.6.1
dev: true
registry.npmmirror.com/@vue/compiler-dom/3.2.14:
resolution: {integrity: sha1-rN2rrpRwTfVDRI4qwx/kdqcNgwc=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-dom/download/@vue/compiler-dom-3.2.14.tgz}
name: '@vue/compiler-dom'
version: 3.2.14
dependencies:
'@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.14
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.14
dev: true
registry.npmmirror.com/@vue/compiler-sfc/3.2.14:
resolution: {integrity: sha1-9I7v6MM1AtWGHMG7/l/Svw5n0tI=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-sfc/download/@vue/compiler-sfc-3.2.14.tgz}
name: '@vue/compiler-sfc'
version: 3.2.14
dependencies:
'@babel/parser': registry.nlark.com/@babel/parser/7.15.6
'@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.14
'@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.14
'@vue/compiler-ssr': registry.npmmirror.com/@vue/compiler-ssr/3.2.14
'@vue/ref-transform': registry.npmmirror.com/@vue/ref-transform/3.2.14
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.14
estree-walker: registry.nlark.com/estree-walker/2.0.2
magic-string: registry.nlark.com/magic-string/0.25.7
postcss: registry.nlark.com/postcss/8.3.6
source-map: registry.nlark.com/source-map/0.6.1
dev: true
registry.npmmirror.com/@vue/compiler-ssr/3.2.14:
resolution: {integrity: sha1-dSBMEHldYd0/9FsPmbqXs9hMrhE=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-ssr/download/@vue/compiler-ssr-3.2.14.tgz}
name: '@vue/compiler-ssr'
version: 3.2.14
dependencies:
'@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.14
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.14
dev: true
registry.npmmirror.com/@vue/ref-transform/3.2.14:
resolution: {integrity: sha1-qnPLmasI1PyAjrpjO5wC2VTNoxo=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/ref-transform/download/@vue/ref-transform-3.2.14.tgz}
name: '@vue/ref-transform'
version: 3.2.14
dependencies:
'@babel/parser': registry.nlark.com/@babel/parser/7.15.6
'@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.14
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.14
estree-walker: registry.nlark.com/estree-walker/2.0.2
magic-string: registry.nlark.com/magic-string/0.25.7
dev: true
registry.npmmirror.com/@vue/shared/3.2.14:
resolution: {integrity: sha1-m4ggmKAEuZUSS3V3s1cTWmbZIu8=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/shared/download/@vue/shared-3.2.14.tgz}
name: '@vue/shared'
version: 3.2.14
dev: true
registry.npmmirror.com/colorette/1.3.0:
resolution: {integrity: sha1-/0XS8O2yRAadO3cq3rBP7TjQoK8=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/colorette/download/colorette-1.3.0.tgz}
name: colorette
version: 1.3.0
dev: true
registry.npmmirror.com/unplugin-vue-components/0.15.2_vite@2.5.10+vue@3.2.10:
resolution: {integrity: sha1-R8SEYUz8KvhOdpyr7DhW0ghIzt0=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/unplugin-vue-components/download/unplugin-vue-components-0.15.2.tgz}
id: registry.npmmirror.com/unplugin-vue-components/0.15.2

View File

@ -0,0 +1,108 @@
<template>
<div
class="relative flex-y-center h-34px -mr-20px cursor-pointer"
:class="{ 'z-10': isHover, 'z-11': isActive }"
@mouseenter="handleMouseOnTab('enter')"
@mouseleave="handleMouseOnTab('leave')"
>
<div class="relative w-10px h-full">
<div class="absolute-lt w-full h-full rounded-br-8px overflow-hidden bg-white z-3"></div>
<div
class="absolute-rb w-full h-10px z-2 bg-opacity-10"
:class="{ 'bg-primary': isActive, 'bg-black': !isActive && isHover }"
></div>
</div>
<div
class="flex-y-center h-full rounded-t-8px bg-opacity-10"
:class="{ 'bg-primary': isActive, 'bg-black': !isActive && isHover }"
>
<div class="w-16px">
<n-divider v-if="!isHover && !isActive" :vertical="true" class="!bg-gray-300" />
</div>
<span :class="[closable ? 'pr-24px' : 'pr-16px']">
<slot></slot>
</span>
<icon-close v-if="closable" :is-primary="isActive" @click="handleClose" />
<div v-if="closable" class="w-8px"></div>
</div>
<div class="relative w-10px h-full">
<div class="absolute-lt w-full h-full rounded-bl-8px overflow-hidden bg-white z-3"></div>
<div
class="absolute-lb w-full h-10px bg-opacity-10 z-2"
:class="{ 'bg-primary': isActive, 'bg-black': !isActive && isHover }"
></div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { NDivider } from 'naive-ui';
import { useBoolean } from '@/hooks';
import { IconClose } from '../../common';
const props = defineProps({
currentIndex: {
type: Number,
required: true
},
activeIndex: {
type: Number,
required: true
},
hoverIndex: {
type: Number,
default: NaN
},
closable: {
type: Boolean,
default: true
}
});
const emit = defineEmits(['close', 'update:hoverIndex']);
const { bool: isHover, setTrue, setFalse } = useBoolean();
const isActive = computed(() => props.currentIndex === props.activeIndex);
const hoveredIndex = ref(props.hoverIndex);
function setHoverIndex(index: number) {
hoveredIndex.value = index;
}
function resetHoverIndex() {
hoveredIndex.value = NaN;
}
function handleMouseOnTab(mode: 'enter' | 'leave') {
if (mode === 'enter') {
setTrue();
setHoverIndex(props.currentIndex);
} else {
setFalse();
resetHoverIndex();
}
}
function handleClose(e: MouseEvent) {
e.stopPropagation();
emit('close');
}
watch(
() => props.hoverIndex,
newValue => {
setHoverIndex(newValue);
}
);
watch(hoveredIndex, newValue => {
emit('update:hoverIndex', newValue);
});
watch(
() => props.activeIndex,
() => {
resetHoverIndex();
}
);
</script>
<style scoped></style>

View File

@ -0,0 +1,6 @@
<template>
<div></div>
</template>
<script setup lang="ts"></script>
<style scoped></style>

View File

@ -1,4 +1,5 @@
import BrowserTabItem from './BrowserTabItem.vue';
import LeftTabRadius from './LeftTabRadius.vue';
import RightTabRadius from './RightTabRadius.vue';
export { LeftTabRadius, RightTabRadius };
export { BrowserTabItem, LeftTabRadius, RightTabRadius };

View File

@ -0,0 +1,117 @@
<template>
<div
class="
relative
inline-flex-center
h-30px
px-32px
transition-background
duration-400
ease-in-out
bg-opacity-10
cursor-pointer
"
:class="{ 'text-primary bg-primary z-3': active, 'bg-black z-2': isHover && !active }"
@mouseenter="handleMouseOnTab('enter')"
@mouseleave="handleMouseOnTab('leave')"
>
<span>
<slot></slot>
</span>
<div
v-if="closable"
class="transition-width duration-400 ease-in-out overflow-hidden"
:class="[isHover ? 'w-18px' : 'w-0']"
>
<icon-close :is-primary="active" @click="handleClose" />
</div>
<left-tab-radius
class="transition-opacity duration-400 ease-in-out"
:class="[showRadius ? 'opacity-100' : 'opacity-0']"
:is-primary="active"
:is-hover="isHover"
:is-left-hover="isLeftHover"
/>
<right-tab-radius
class="transition-opacity duration-400 ease-out"
:class="[showRadius ? 'opacity-100' : 'opacity-0']"
:is-primary="active"
:is-hover="isHover"
:is-right-hover="isRightHover"
/>
</div>
</template>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { useBoolean } from '@/hooks';
import { IconClose } from '../common';
import { LeftTabRadius, RightTabRadius } from './components';
const props = defineProps({
currentIndex: {
type: Number,
required: true
},
activeIndex: {
type: Number,
required: true
},
hoverIndex: {
type: Number,
default: NaN
},
closable: {
type: Boolean,
default: true
}
});
const emit = defineEmits(['close', 'update:hoverIndex']);
const { bool: isHover, setTrue, setFalse } = useBoolean();
const hoveredIndex = ref(props.hoverIndex);
function setHoverIndex(index: number) {
hoveredIndex.value = index;
}
function resetHoverIndex() {
hoveredIndex.value = NaN;
}
const active = computed(() => props.currentIndex === props.activeIndex);
const showRadius = computed(() => isHover.value || active.value);
const isLeftHover = computed(() => active.value && props.activeIndex === hoveredIndex.value + 1);
const isRightHover = computed(() => active.value && props.activeIndex === hoveredIndex.value - 1);
function handleMouseOnTab(mode: 'enter' | 'leave') {
if (mode === 'enter') {
setTrue();
setHoverIndex(props.currentIndex);
} else {
setFalse();
resetHoverIndex();
}
}
function handleClose(e: MouseEvent) {
e.stopPropagation();
emit('close');
}
watch(
() => props.hoverIndex,
newValue => {
setHoverIndex(newValue);
}
);
watch(hoveredIndex, newValue => {
emit('update:hoverIndex', newValue);
});
watch(
() => props.activeIndex,
() => {
resetHoverIndex();
}
);
</script>
<style scoped></style>

View File

@ -1,117 +1,29 @@
<template>
<div
class="
relative
inline-flex-center
h-30px
px-32px
transition-background
duration-400
ease-in-out
bg-opacity-10
cursor-pointer
"
:class="{ 'text-primary bg-primary z-3': active, 'bg-black z-2': isHover && !active }"
@mouseenter="handleMouseOnTab('enter')"
@mouseleave="handleMouseOnTab('leave')"
>
<span>
<slot></slot>
</span>
<div
v-if="closable"
class="transition-width duration-400 ease-in-out overflow-hidden"
:class="[isHover ? 'w-18px' : 'w-0']"
<div class="flex items-end h-full">
<browser-tab-item
v-for="(item, index) in app.multiTab.routes"
:key="item.path"
v-model:hover-index="hoverIndex"
:current-index="index"
:active-index="app.activeMultiTabIndex"
:closable="item.name !== ROUTE_HOME.name"
@click="handleClickTab(item.fullPath)"
@close="removeMultiTab(item.fullPath)"
>
<icon-close :is-primary="active" @click="handleClose" />
</div>
<left-tab-radius
class="transition-opacity duration-400 ease-in-out"
:class="[showRadius ? 'opacity-100' : 'opacity-0']"
:is-primary="active"
:is-hover="isHover"
:is-left-hover="isLeftHover"
/>
<right-tab-radius
class="transition-opacity duration-400 ease-out"
:class="[showRadius ? 'opacity-100' : 'opacity-0']"
:is-primary="active"
:is-hover="isHover"
:is-right-hover="isRightHover"
/>
{{ item.meta?.title }}
</browser-tab-item>
</div>
</template>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { useBoolean } from '@/hooks';
import { IconClose } from '../common';
import { LeftTabRadius, RightTabRadius } from './components';
<script setup lang="ts">
import { ref } from 'vue';
import { useAppStore } from '@/store';
import { ROUTE_HOME } from '@/router';
import { BrowserTabItem } from './components';
const props = defineProps({
currentIndex: {
type: Number,
required: true
},
activeIndex: {
type: Number,
required: true
},
hoverIndex: {
type: Number,
default: NaN
},
closable: {
type: Boolean,
default: true
}
});
const emit = defineEmits(['close', 'update:hoverIndex']);
const app = useAppStore();
const { removeMultiTab, handleClickTab } = useAppStore();
const { bool: isHover, setTrue, setFalse } = useBoolean();
const hoveredIndex = ref(props.hoverIndex);
function setHoverIndex(index: number) {
hoveredIndex.value = index;
}
function resetHoverIndex() {
hoveredIndex.value = NaN;
}
const active = computed(() => props.currentIndex === props.activeIndex);
const showRadius = computed(() => isHover.value || active.value);
const isLeftHover = computed(() => active.value && props.activeIndex === hoveredIndex.value + 1);
const isRightHover = computed(() => active.value && props.activeIndex === hoveredIndex.value - 1);
function handleMouseOnTab(mode: 'enter' | 'leave') {
if (mode === 'enter') {
setTrue();
setHoverIndex(props.currentIndex);
} else {
setFalse();
resetHoverIndex();
}
}
function handleClose(e: MouseEvent) {
e.stopPropagation();
emit('close');
}
watch(
() => props.hoverIndex,
newValue => {
setHoverIndex(newValue);
}
);
watch(hoveredIndex, newValue => {
emit('update:hoverIndex', newValue);
});
watch(
() => props.activeIndex,
() => {
resetHoverIndex();
}
);
const hoverIndex = ref(NaN);
</script>
<style scoped></style>

View File

@ -1,7 +1,7 @@
<template>
<div
class="relative flex-center w-18px h-18px text-14px"
:class="{ 'text-primary': isPrimary }"
:class="[isPrimary ? 'text-primary' : 'text-gray-400']"
@mouseenter="setTrue"
@mouseleave="setFalse"
>

View File

@ -21,21 +21,7 @@
{{ item.meta?.title }}
</button-tab>
</n-space>
<n-space v-if="theme.multiTabStyle.mode === 'browser'" :align="'flex-end'" :size="0" class="h-full px-16px">
<browser-tab
v-for="(item, index) in app.multiTab.routes"
:key="item.path"
v-model:hover-index="hoverIndex"
:current-index="index"
:active-index="app.activeMultiTabIndex"
:closable="item.name !== ROUTE_HOME.name"
@click="handleClickTab(item.fullPath)"
@close="removeMultiTab(item.fullPath)"
@contextmenu="handleContextMenu($event, item.fullPath)"
>
{{ item.meta?.title }}
</browser-tab>
</n-space>
<browser-tab />
<reload-button />
<context-menu
:visible="dropdownVisible"

View File

@ -14,6 +14,8 @@ const app = useAppStore();
const theme = useThemeStore();
const title = useAppTitle();
const showTitle = computed(() => !app.menu.collapsed || !theme.isVerticalNav);
const showTitle = computed(
() => !theme.isVerticalNav || (!app.menu.collapsed && theme.navStyle.mode !== 'vertical-mix')
);
</script>
<style scoped></style>