style: Add elNamespace

feat(component): Add namespace of class
This commit is contained in:
kailong321200875
2022-01-23 10:11:13 +08:00
parent e20fa76cad
commit d847ccb098
38 changed files with 507 additions and 302 deletions

View File

@@ -3,6 +3,11 @@ import { computed } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { ConfigGlobal } from '@/components/ConfigGlobal'
import { isDark } from '@/utils/is'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('app')
const appStore = useAppStore()
@@ -20,12 +25,12 @@ initDark()
<template>
<ConfigGlobal :size="currentSize">
<RouterView :class="{ 'v-grey__mode': greyMode }" />
<RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" />
</ConfigGlobal>
</template>
<style lang="less">
@prefix-cls: ~'@{namespace}-grey';
@prefix-cls: ~'@{namespace}-app';
.size {
width: 100%;
@@ -44,7 +49,7 @@ body {
}
}
.@{prefix-cls}__mode {
.@{prefix-cls}-grey-mode {
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg>

After

Width:  |  Height:  |  Size: 731 B

View File

@@ -1,7 +1,15 @@
<script setup lang="ts">
import { ElBacktop } from 'element-plus'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls, variables } = useDesign()
const prefixCls = getPrefixCls('backtop')
</script>
<template>
<ElBacktop target=".v-content .el-scrollbar__wrap" />
<ElBacktop
:class="`${prefixCls}-backtop`"
:target="`.${variables.namespace}-layout-content-scrollbar .${variables.elNamespace}-scrollbar__wrap`"
/>
</template>

View File

@@ -9,6 +9,11 @@ import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
import { useI18n } from '@/hooks/web/useI18n'
import { Icon } from '@/components/Icon'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('breadcrumb')
const appStore = useAppStore()
@@ -72,7 +77,7 @@ export default defineComponent({
)
return () => (
<ElBreadcrumb separator="/" class="flex items-center h-full ml-[10px]">
<ElBreadcrumb separator="/" class={`${prefixCls} flex items-center h-full ml-[10px]`}>
<TransitionGroup appear enter-active-class="animate__animated animate__fadeInRight">
{renderBreadcrumb()}
</TransitionGroup>
@@ -83,36 +88,39 @@ export default defineComponent({
</script>
<style lang="less" scoped>
:deep(.el-breadcrumb__item) {
display: flex;
@prefix-cls: ~'@{namespace}-breadcrumb';
.el-breadcrumb__inner {
.@{prefix-cls} {
:deep(&__item) {
display: flex;
align-items: center;
color: var(--top-header-text-color);
.@{prefix-cls}__inner {
display: flex;
align-items: center;
color: var(--top-header-text-color);
&:hover {
color: var(--el-color-primary);
&:hover {
color: var(--el-color-primary);
}
}
}
}
:deep(.el-breadcrumb__item):not(:last-child) {
.el-breadcrumb__inner {
color: var(--top-header-text-color);
:deep(&__item):not(:last-child) {
.@{prefix-cls}__inner {
color: var(--top-header-text-color);
&:hover {
color: var(--el-color-primary);
&:hover {
color: var(--el-color-primary);
}
}
}
}
:deep(.el-breadcrumb__item):last-child {
.el-breadcrumb__inner {
color: var(--el-text-color-placeholder);
&:hover {
:deep(&__item):last-child {
.@{prefix-cls}__inner {
color: var(--el-text-color-placeholder);
&:hover {
color: var(--el-text-color-placeholder);
}
}
}
}

View File

@@ -2,6 +2,11 @@
import { computed, unref } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('collapse')
defineProps({
color: propTypes.string.def('')
@@ -18,7 +23,7 @@ const toggleCollapse = () => {
</script>
<template>
<div>
<div :class="prefixCls">
<Icon
:size="18"
:icon="collapse ? 'ant-design:menu-unfold-outlined' : 'ant-design:menu-fold-outlined'"

View File

@@ -6,6 +6,11 @@ import { useLocaleStore } from '@/store/modules/locale'
import { useWindowSize } from '@vueuse/core'
import { useAppStore } from '@/store/modules/app'
import { setCssVar } from '@/utils'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls, variables } = useDesign()
const prefixCls = getPrefixCls('config-global')
const appStore = useAppStore()
@@ -48,7 +53,13 @@ const currentLocale = computed(() => localeStore.currentLocale)
</script>
<template>
<ElConfigProvider :locale="currentLocale.elLocale" :message="{ max: 1 }" :size="size">
<ElConfigProvider
:clss="prefixCls"
:namespace="variables.elNamespace"
:locale="currentLocale.elLocale"
:message="{ max: 1 }"
:size="size"
>
<slot></slot>
</ElConfigProvider>
</template>

View File

@@ -2,6 +2,11 @@
import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
import { PropType } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('context-menu')
const { t } = useI18n()
@@ -23,6 +28,7 @@ const command = (item: contextMenuSchema) => {
<template>
<ElDropdown
:class="prefixCls"
:trigger="trigger"
placement="bottom-start"
@command="command"
@@ -44,9 +50,3 @@ const command = (item: contextMenuSchema) => {
</template>
</ElDropdown>
</template>
<style lang="less">
.v-context-menu-popper {
min-width: 150px;
}
</style>

View File

@@ -0,0 +1,3 @@
import CountTo from './src/CountTo.vue'
export { CountTo }

View File

@@ -2,12 +2,17 @@
import { reactive, computed, watch, onMounted, unref, toRef, PropType } from 'vue'
import { isNumber } from '@/utils/is'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('count-to')
const props = defineProps({
startVal: propTypes.number.def(0),
endVal: propTypes.number.def(2021),
duration: propTypes.number.def(3000),
autoplay: propTypes.bool.def(false),
autoplay: propTypes.bool.def(true),
decimals: propTypes.number.validate((value: number) => value >= 0).def(0),
decimal: propTypes.string.def('.'),
separator: propTypes.string.def(','),
@@ -169,7 +174,7 @@ defineExpose({
</script>
<template>
<span>
<span :class="prefixCls">
{{ displayValue }}
</span>
</template>

View File

@@ -7,6 +7,11 @@ import { propTypes } from '@/utils/propTypes'
import { computed, PropType, ref, unref, watch, onMounted, onBeforeUnmount, onActivated } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { isString } from '@/utils/is'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('echart')
const appStore = useAppStore()
@@ -106,5 +111,5 @@ onActivated(() => {
</script>
<template>
<div ref="elRef" :class="$attrs.class" :style="styles" />
<div ref="elRef" :class="[$attrs.class, prefixCls]" :style="styles" />
</template>

View File

@@ -1,6 +1,11 @@
<script setup lang="ts">
import { useAppStore } from '@/store/modules/app'
import { computed } from 'vue'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('footer')
const appStore = useAppStore()
@@ -8,5 +13,10 @@ const title = computed(() => appStore.getTitle)
</script>
<template>
<div class="text-center text-[var(--el-text-color-placeholder)]">Copyright ©2021 {{ title }}</div>
<div
:class="prefixCls"
class="text-center text-[var(--el-text-color-placeholder)] bg-[var(--app-contnet-bg-color)] h-[var(--app-footer-height)] leading-[var(--app-footer-height)]"
>
Copyright ©2021 {{ title }}
</div>
</template>

View File

@@ -15,6 +15,11 @@ import {
import { useRenderSelect } from './components/useRenderSelect'
import { useRenderRadio } from './components/useRenderRadio'
import { useRenderChcekbox } from './components/useRenderChcekbox'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('form')
export default defineComponent({
name: 'Form',
@@ -194,7 +199,7 @@ export default defineComponent({
}
return () => (
<ElForm ref={elFormRef} {...getFormBindValue()} model={formModel} class="v-form">
<ElForm ref={elFormRef} {...getFormBindValue()} model={formModel} class={prefixCls}>
{{
// 如果需要自定义,就什么都不渲染,而是提供默认插槽
default: () => (isCustom ? getSlot(slots, 'default') : renderWrap())

View File

@@ -3,6 +3,11 @@ import { computed, unref, ref, watch, nextTick } from 'vue'
import { ElIcon } from 'element-plus'
import { propTypes } from '@/utils/propTypes'
import Iconify from '@purge-icons/generated'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('icon')
const props = defineProps({
// icon name
@@ -61,7 +66,7 @@ watch(
</script>
<template>
<ElIcon class="v-icon" :size="size" :color="color">
<ElIcon :class="prefixCls" :size="size" :color="color">
<svg v-if="isLocal" aria-hidden="true">
<use :xlink:href="symbolId" />
</svg>

View File

@@ -5,6 +5,11 @@ import { propTypes } from '@/utils/propTypes'
import { useConfigGlobal } from '@/hooks/web/useConfigGlobal'
import { zxcvbn } from '@zxcvbn-ts/core'
import type { ZxcvbnResult } from '@zxcvbn-ts/core'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('input-password')
const props = defineProps({
// 是否显示密码强度
@@ -55,7 +60,7 @@ const getIconName = computed(() =>
</script>
<template>
<div :class="['v-input-password', `v-input-password--${configGlobal?.size}`]">
<div :class="[prefixCls, `${prefixCls}--${configGlobal?.size}`]">
<ElInput v-bind="$attrs" v-model="valueRef" :type="textType">
<template #suffix>
<Icon class="el-input__icon cursor-pointer" :icon="getIconName" @click="changeTextType" />
@@ -63,9 +68,10 @@ const getIconName = computed(() =>
</ElInput>
<div
v-if="strength"
class="v-input-password__bar relative h-6px mt-10px mb-6px mr-auto ml-auto"
:class="`${prefixCls}__bar`"
class="relative h-6px mt-10px mb-6px mr-auto ml-auto"
>
<div class="v-input-password__bar--fill" :data-score="getPasswordStrength"></div>
<div :class="`${prefixCls}__bar--fill`" :data-score="getPasswordStrength"></div>
</div>
</div>
</template>
@@ -74,7 +80,7 @@ const getIconName = computed(() =>
@prefix-cls: ~'@{namespace}-input-password';
.@{prefix-cls} {
:deep(.el-input__clear) {
:deep(.@{elNamespace}-input__clear) {
margin-left: 5px;
}

View File

@@ -4,6 +4,11 @@ import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
import { useLocaleStore } from '@/store/modules/locale'
import { useLocale } from '@/hooks/web/useLocale'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('locale-dropdown')
defineProps({
color: propTypes.string.def('')
@@ -28,7 +33,7 @@ const setLang = (lang: LocaleType) => {
</script>
<template>
<ElDropdown trigger="click" @command="setLang">
<ElDropdown :class="prefixCls" trigger="click" @command="setLang">
<Icon
:size="18"
icon="ion:language-sharp"

View File

@@ -1,6 +1,11 @@
<script setup lang="ts">
import { ref, watch, computed, onMounted, unref } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('logo')
const appStore = useAppStore()
@@ -52,10 +57,8 @@ watch(
<template>
<router-link
:class="[
'v-logo',
{
'v-logo__Top': layout !== 'classic'
},
prefixCls,
layout !== 'classic' ? `${prefixCls}__Top` : '',
'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative'
]"
to="/"
@@ -79,7 +82,3 @@ watch(
</div>
</router-link>
</template>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-logo';
</style>

View File

@@ -7,6 +7,11 @@ import type { LayoutType } from '@/config/app'
import { useRenderMenuItem } from './components/useRenderMenuItem'
import { useRouter } from 'vue-router'
import { isUrl } from '@/utils/is'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('menu')
export default defineComponent({
name: 'Menu',
@@ -66,7 +71,7 @@ export default defineComponent({
return () => (
<div
class={[
`v-menu v-menu__${unref(menuMode)}`,
`${prefixCls} ${prefixCls}__${unref(menuMode)}`,
'h-[100%] overflow-hidden z-100 flex-col bg-[var(--left-menu-bg-color)]',
{
'w-[var(--left-menu-min-width)]': unref(collapse) && unref(layout) !== 'cutMenu',
@@ -126,20 +131,20 @@ export default defineComponent({
content: '';
}
:deep(.el-menu) {
:deep(.@{elNamespace}-menu) {
width: 100% !important;
border-right: none;
// 设置选中时子标题的颜色
.is-active {
& > .el-sub-menu__title {
& > .@{elNamespace}-sub-menu__title {
color: var(--left-menu-text-active-color) !important;
}
}
// 设置子菜单悬停的高亮和背景色
.el-sub-menu__title,
.el-menu-item {
.@{elNamespace}-sub-menu__title,
.@{elNamespace}-menu-item {
&:hover {
color: var(--left-menu-text-active-color) !important;
background-color: var(--left-menu-bg-color) !important;
@@ -147,8 +152,8 @@ export default defineComponent({
}
// 设置选中时的高亮背景和高亮颜色
.el-sub-menu.is-active,
.el-menu-item.is-active {
.@{elNamespace}-sub-menu.is-active,
.@{elNamespace}-menu-item.is-active {
color: var(--left-menu-text-active-color) !important;
background-color: var(--left-menu-bg-active-color) !important;
@@ -157,7 +162,7 @@ export default defineComponent({
}
}
.el-menu-item.is-active {
.@{elNamespace}-menu-item.is-active {
position: relative;
&:after {
@@ -166,20 +171,20 @@ export default defineComponent({
}
// 设置子菜单的背景颜色
.el-menu {
.el-sub-menu__title,
.el-menu-item:not(.is-active) {
.@{elNamespace}-menu {
.@{elNamespace}-sub-menu__title,
.@{elNamespace}-menu-item:not(.is-active) {
background-color: var(--left-menu-bg-light-color) !important;
}
}
}
// 折叠时的最小宽度
:deep(.el-menu--collapse) {
:deep(.@{elNamespace}-menu--collapse) {
width: var(--left-menu-min-width);
& > .is-active,
& > .is-active > .el-sub-menu__title {
& > .is-active > .@{elNamespace}-sub-menu__title {
position: relative;
background-color: var(--left-menu-collapse-bg-active-color) !important;
@@ -201,17 +206,17 @@ export default defineComponent({
&__horizontal {
height: calc(~'var( - -top-tool-height)') !important;
:deep(.el-menu--horizontal) {
:deep(.@{elNamespace}-menu--horizontal) {
height: calc(~'var( - -top-tool-height)');
border-bottom: none;
// 重新设置底部高亮颜色
& > .el-sub-menu.is-active {
.el-sub-menu__title {
& > .@{elNamespace}-sub-menu.is-active {
.@{elNamespace}-sub-menu__title {
border-bottom-color: var(--el-color-primary) !important;
}
}
.el-menu-item.is-active {
.@{elNamespace}-menu-item.is-active {
position: relative;
&:after {
@@ -219,7 +224,7 @@ export default defineComponent({
}
}
.v-menu__title {
.@{prefix-cls}__title {
/* stylelint-disable-next-line */
max-height: calc(~'var(--top-tool-height) - 2px') !important;
/* stylelint-disable-next-line */

View File

@@ -2,6 +2,11 @@
import { Icon } from '@/components/Icon'
import { useFullscreen } from '@vueuse/core'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('screenfull')
defineProps({
color: propTypes.string.def('')
@@ -15,7 +20,7 @@ const toggleFullscreen = () => {
</script>
<template>
<div @click="toggleFullscreen">
<div :class="prefixCls" @click="toggleFullscreen">
<Icon
:size="18"
:icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'"

View File

@@ -12,6 +12,11 @@ import InterfaceDisplay from './components/InterfaceDisplay.vue'
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
import { useCache } from '@/hooks/web/useCache'
import { useClipboard } from '@vueuse/core'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('setting')
const appStore = useAppStore()
@@ -184,7 +189,8 @@ const clear = () => {
<template>
<div
class="v-setting fixed top-[45%] right-0 w-40px h-40px text-center leading-40px bg-[var(--el-color-primary)] cursor-pointer"
:class="prefixCls"
class="fixed top-[45%] right-0 w-40px h-40px text-center leading-40px bg-[var(--el-color-primary)] cursor-pointer"
@click="drawer = true"
>
<Icon icon="ant-design:setting-outlined" color="#fff" />

View File

@@ -1,6 +1,11 @@
<script setup lang="ts">
import { PropType, watch, unref, ref } from 'vue'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('color-radio-picker')
const props = defineProps({
schema: {
@@ -33,11 +38,11 @@ watch(
</script>
<template>
<div class="v-color-radio-picker flex flex-wrap space-x-14px">
<div :class="prefixCls" class="flex flex-wrap space-x-14px">
<span
v-for="(item, i) in schema"
:key="`radio-${i}`"
class="v-color-radio-picker w-20px h-20px cursor-pointer rounded-2px border-solid border-gray-300 border-2px text-center leading-20px mb-5px"
class="w-20px h-20px cursor-pointer rounded-2px border-solid border-gray-300 border-2px text-center leading-20px mb-5px"
:class="{ 'is-active': colorVal === item }"
:style="{
background: item

View File

@@ -3,6 +3,11 @@ import { ElSwitch } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useAppStore } from '@/store/modules/app'
import { computed, ref, watch } from 'vue'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('interface-display')
const appStore = useAppStore()
@@ -98,7 +103,7 @@ watch(
</script>
<template>
<div class="v-interface-display">
<div :class="prefixCls">
<div class="flex justify-between items-center">
<span class="text-14px">{{ t('setting.breadcrumb') }}</span>
<ElSwitch v-model="breadcrumb" @change="breadcrumbChange" />

View File

@@ -1,6 +1,11 @@
<script setup lang="ts">
import { useAppStore } from '@/store/modules/app'
import { computed } from 'vue'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('layout-radio-picker')
const appStore = useAppStore()
@@ -8,10 +13,11 @@ const layout = computed(() => appStore.getLayout)
</script>
<template>
<div class="v-layout-radio-picker flex flex-wrap space-x-14px">
<div :class="prefixCls" class="flex flex-wrap space-x-14px">
<div
:class="[
'v-layout-radio-picker__classic relative w-56px h-48px cursor-pointer bg-gray-300',
`${prefixCls}__classic`,
'relative w-56px h-48px cursor-pointer bg-gray-300',
{
'is-acitve': layout === 'classic'
}
@@ -20,7 +26,8 @@ const layout = computed(() => appStore.getLayout)
></div>
<div
:class="[
'v-layout-radio-picker__top-left relative w-56px h-48px cursor-pointer bg-gray-300',
`${prefixCls}__top-left`,
'relative w-56px h-48px cursor-pointer bg-gray-300',
{
'is-acitve': layout === 'topLeft'
}
@@ -29,7 +36,8 @@ const layout = computed(() => appStore.getLayout)
></div>
<div
:class="[
'v-layout-radio-picker__top relative w-56px h-48px cursor-pointer bg-gray-300',
`${prefixCls}__top`,
'relative w-56px h-48px cursor-pointer bg-gray-300',
{
'is-acitve': layout === 'top'
}
@@ -38,7 +46,8 @@ const layout = computed(() => appStore.getLayout)
></div>
<div
:class="[
'v-layout-radio-picker__cut-menu relative w-56px h-48px cursor-pointer bg-gray-300',
`${prefixCls}__cut-menu`,
'relative w-56px h-48px cursor-pointer bg-gray-300',
{
'is-acitve': layout === 'cutMenu'
}

View File

@@ -4,6 +4,11 @@ import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
import { useAppStore } from '@/store/modules/app'
import { useI18n } from '@/hooks/web/useI18n'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('size-dropdown')
defineProps({
color: propTypes.string.def('')
@@ -21,7 +26,7 @@ const setCurrentSize = (size: ElememtPlusSzie) => {
</script>
<template>
<ElDropdown trigger="click" @command="setCurrentSize">
<ElDropdown :class="prefixCls" trigger="click" @command="setCurrentSize">
<Icon :size="18" icon="mdi:format-size" :color="color" class="cursor-pointer" />
<template #dropdown>
<ElDropdownMenu>

View File

@@ -10,6 +10,11 @@ import { useRouter } from 'vue-router'
import { pathResolve } from '@/utils/routerHelper'
import { cloneDeep } from 'lodash-es'
import { filterMenusPath, initTabMap, tabPathMap } from './helper'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('tab-menu')
export default defineComponent({
name: 'TabMenu',
@@ -102,7 +107,8 @@ export default defineComponent({
return () => (
<div
class={[
'v-tab-menu relative bg-[var(--left-menu-bg-color)] top-1px',
prefixCls,
'relative bg-[var(--left-menu-bg-color)] top-1px',
{
'w-[var(--tab-menu-max-width)]': !unref(collapse),
'w-[var(--tab-menu-min-width)]': unref(collapse)
@@ -115,7 +121,7 @@ export default defineComponent({
{() => {
return unref(tabRouters).map((v) => {
const item = (
v?.children?.length && v?.children?.length > 1
v.meta?.alwaysShow || (v?.children?.length && v?.children?.length > 1)
? v
: {
...(v?.children && v?.children[0]),
@@ -125,7 +131,8 @@ export default defineComponent({
return (
<div
class={[
'v-tab-menu-item text-center text-12px relative py-12px cursor-pointer',
`${prefixCls}__item`,
'text-center text-12px relative py-12px cursor-pointer',
{
'is-active': isActice(v.path)
}
@@ -147,7 +154,10 @@ export default defineComponent({
</div>
</ElScrollbar>
<div
class="v-tab-menu-collapse text-center h-[var(--tab-menu-collapse-height)] leading-[var(--tab-menu-collapse-height)] cursor-pointer"
class={[
`${prefixCls}--collapse`,
'text-center h-[var(--tab-menu-collapse-height)] leading-[var(--tab-menu-collapse-height)] cursor-pointer'
]}
onClick={setCollapse}
>
<Icon icon={unref(collapse) ? 'ep:d-arrow-right' : 'ep:d-arrow-left'}></Icon>
@@ -186,7 +196,7 @@ export default defineComponent({
content: '';
}
&-item {
&__item {
color: var(--left-menu-text-color);
transition: all var(--transition-time-02);
@@ -196,7 +206,7 @@ export default defineComponent({
}
}
&-collapse {
&--collapse {
color: var(--left-menu-text-color);
background-color: var(--left-menu-bg-light-color);
border-top: 1px solid var(--left-menu-border-color);

View File

@@ -7,6 +7,11 @@ import { useTagsViewStore } from '@/store/modules/tagsView'
import { useI18n } from '@/hooks/web/useI18n'
import { filterAffixTags } from './helper'
import { ContextMenu } from '@/components/ContextMenu'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('tags-view')
const { t } = useI18n()
@@ -125,9 +130,10 @@ watch(
</script>
<template>
<div class="v-tags-view h-[var(--tags-view-height)] flex w-full relative">
<div :class="prefixCls" class="h-[var(--tags-view-height)] flex w-full relative">
<span
class="v-tags-view__tool w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
:class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
>
<Icon icon="ep:d-arrow-left" color="#333" />
</span>
@@ -195,9 +201,9 @@ watch(
v-for="item in visitedViews"
:key="item.fullPath"
:class="[
'v-tags-view__item',
`${prefixCls}__item`,
item?.meta?.affix ? `${prefixCls}__item--affix` : '',
{
'v-tags-view__item--affix': item?.meta?.affix,
'is-active': isActive(item)
}
]"
@@ -209,7 +215,7 @@ watch(
>
{{ t(item?.meta?.title as string) }}
<Icon
class="v-tags-view__item--close"
:class="`${prefixCls}__item--close`"
color="#333"
icon="ant-design:close-outlined"
:size="12"
@@ -222,12 +228,14 @@ watch(
</ElScrollbar>
</div>
<span
class="v-tags-view__tool w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
:class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
>
<Icon icon="ep:d-arrow-right" color="#333" />
</span>
<span
class="v-tags-view__tool w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
:class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"
@click="refreshSelectedTag(selectedTag)"
>
<Icon icon="ant-design:reload-outlined" color="#333" />
@@ -284,7 +292,8 @@ watch(
]"
>
<span
class="v-tags-view__tool w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block"
:class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block"
>
<Icon icon="ant-design:setting-outlined" color="#333" />
</span>
@@ -296,7 +305,7 @@ watch(
@prefix-cls: ~'@{namespace}-tags-view';
.@{prefix-cls} {
:deep(.el-scrollbar__view) {
:deep(.@{elNamespace}-scrollbar__view) {
height: 100%;
}

View File

@@ -3,6 +3,11 @@ import { ref } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { ElSwitch } from 'element-plus'
import { useIcon } from '@/hooks/web/useIcon'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('theme-switch')
const Sun = useIcon({ icon: 'emojione-monotone:sun', color: '#fde047' })
@@ -23,7 +28,7 @@ const themeChange = (val: boolean) => {
<template>
<ElSwitch
class="v-theme-switch"
:class="prefixCls"
v-model="isDark"
inline-prompt
:border-color="blackColor"
@@ -34,7 +39,3 @@ const themeChange = (val: boolean) => {
@change="themeChange"
/>
</template>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-theme-switch';
</style>

View File

@@ -5,6 +5,11 @@ import { useCache } from '@/hooks/web/useCache'
import { resetRouter } from '@/router'
import { useRouter } from 'vue-router'
import { loginOutApi } from '@/api/login'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('user-info')
const { t } = useI18n()
@@ -31,7 +36,7 @@ const loginOut = () => {
</script>
<template>
<ElDropdown trigger="click">
<ElDropdown :class="prefixCls" trigger="click">
<div class="flex items-center">
<img src="@/assets/imgs/avatar.png" alt="" class="w-[calc(var(--tags-view-height)-10px)]" />
<span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">Archer</span>

View File

@@ -1,9 +1,14 @@
<script lang="tsx">
import { computed, defineComponent, unref } from 'vue'
import { useAppStore } from '@/store/modules/app'
// import { Backtop } from '@/components/Backtop'
import { Backtop } from '@/components/Backtop'
import { Setting } from '@/components/Setting'
import { useRenderLayout } from './components/useRenderLayout'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('layout')
const appStore = useAppStore()
@@ -42,7 +47,7 @@ export default defineComponent({
name: 'Layout',
setup() {
return () => (
<section class={['v-app', `v-app__${layout.value}`, 'w-[100%] h-[100%] relative']}>
<section class={[prefixCls, `${prefixCls}__${layout.value}`, 'w-[100%] h-[100%] relative']}>
{mobile.value && !collapse.value ? (
<div
class="absolute top-0 left-0 w-full h-full opacity-30 z-99 bg-[var(--el-color-black)]"
@@ -52,7 +57,7 @@ export default defineComponent({
{renderLayout()}
{/*<Backtop></Backtop>*/}
<Backtop></Backtop>
<Setting></Setting>
</section>
@@ -62,11 +67,7 @@ export default defineComponent({
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-app';
:deep(.@{namespace}-content) {
.el-scrollbar__view {
height: 100%;
}
:deep(.@{elNamespace}-scrollbar__view) {
height: 100% !important;
}
</style>

View File

@@ -22,17 +22,19 @@ const getCaches = computed((): string[] => {
<template>
<section
:class="[
'p-[var(--app-content-padding)] w-[100%]',
'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-contnet-bg-color)]',
{
'!min-h-[calc(100%-calc(var(--app-content-padding)*2))]':
fixedHeader && layout === 'classic' && footer,
'!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-calc(var(--app-content-padding)*2))]':
'!min-h-[calc(100%-var(--app-footer-height))]':
fixedHeader && (layout === 'classic' || layout === 'topLeft') && footer,
'!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-var(--app-footer-height))]':
((!fixedHeader && layout === 'classic') || layout === 'top') && footer,
'!min-h-[calc(100%-var(--tags-view-height))]':
fixedHeader && layout === 'topLeft' && footer,
'!min-h-[calc(100%-var(--tags-view-height)-calc(var(--app-content-padding)*2))]':
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]':
!fixedHeader && layout === 'topLeft' && footer,
'!min-h-[calc(100%-var(--top-tool-height))]': fixedHeader && layout === 'cutMenu' && footer,
'!min-h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))]':
!fixedHeader && layout === 'cutMenu' && footer
}

View File

@@ -7,6 +7,11 @@ import { UserInfo } from '@/components/UserInfo'
import { Screenfull } from '@/components/Screenfull'
import { Breadcrumb } from '@/components/Breadcrumb'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('tool-header')
const appStore = useAppStore()
@@ -34,7 +39,7 @@ export default defineComponent({
return () => (
<div
class={[
'v-tool-header',
prefixCls,
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between'
]}
>

View File

@@ -7,6 +7,11 @@ import { Logo } from '@/components/Logo'
import AppView from './AppView.vue'
import ToolHeader from './ToolHeader.vue'
import { ElScrollbar } from 'element-plus'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('layout-content')
const appStore = useAppStore()
@@ -49,7 +54,7 @@ export const useRenderLayout = () => {
</div>
<div
class={[
'v-content',
prefixCls,
'absolute top-0 h-[100%]',
{
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
@@ -64,6 +69,7 @@ export const useRenderLayout = () => {
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
{
'!h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))] mt-[calc(var(--top-tool-height)+var(--tags-view-height))]':
fixedHeader.value
@@ -109,7 +115,7 @@ export const useRenderLayout = () => {
<Menu class="!h-full"></Menu>
<div
class={[
'v-content',
prefixCls,
'h-[100%]',
{
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
@@ -123,6 +129,7 @@ export const useRenderLayout = () => {
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
{
'!h-[calc(100%-var(--tags-view-height))] mt-[calc(var(--tags-view-height))]':
fixedHeader.value && tagsView.value
@@ -161,10 +168,11 @@ export const useRenderLayout = () => {
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
<ToolHeader></ToolHeader>
</div>
<div class="v-content h-full w-full">
<div class={[prefixCls, 'v-content h-full w-full']}>
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
{
'mt-[var(--tags-view-height)]': fixedHeader.value
}
@@ -202,7 +210,7 @@ export const useRenderLayout = () => {
{/* <Menu class="!h-full"></Menu> */}
<div
class={[
'v-content',
prefixCls,
'h-[100%]',
{
'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)]':
@@ -216,6 +224,7 @@ export const useRenderLayout = () => {
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
{
'!h-[calc(100%-var(--tags-view-height))] mt-[calc(var(--tags-view-height))]':
fixedHeader.value && tagsView.value

View File

@@ -131,8 +131,7 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
name: 'Icons',
meta: {
title: '图标',
icon: 'carbon:skill-level-advanced',
affix: true
icon: 'carbon:skill-level-advanced'
}
}
]

View File

@@ -59,5 +59,9 @@
--app-content-padding: 20px;
--app-contnet-bg-color: #f5f7f9;
--app-footer-height: 50px;
--transition-time-02: 0.2s;
}

View File

@@ -1,7 +1,10 @@
// 命名空间
@namespace: v;
// el命名空间
@elNamespace: el;
// 导出变量
:export {
namespace: @namespace;
elNamespace: @elNamespace;
}

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
// import { ElRow, ElCol } from 'element-plus'
import PanelGroup from './components/PanelGroup.vue'
</script>
<template>
<div>dddd</div>
<PanelGroup />
</template>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
import { ElRow, ElCol, ElCard } from 'element-plus'
import { CountTo } from '@/components/CountTo'
</script>
<template>
<ElRow :gutter="20" class="v-panel">
<ElCol :xl="6" :lg="6" :md="6" :sm="6" :xs="1">
<ElCard shadow="hover">
<div class="v-panel-item flex justify-between">
<div>
<div
class="v-panel-item__icon v-panel-item__icon--peoples p-16px inline-block rounded-6px"
>
<Icon icon="svg-icon:peoples" :size="40" />
</div>
</div>
<div class="flex flex-col justify-between">
<div class="v-panel-item__text">新增用户</div>
<CountTo :start-val="0" :end-val="102400" :duration="2600" />
</div>
</div>
</ElCard>
</ElCol>
</ElRow>
</template>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-panel';
.@{prefix-cls} {
&-item {
&:hover {
:deep(.v-icon) {
color: #fff !important;
}
.@{prefix-cls}-item__icon {
transition: all 0.38s ease-out;
&--peoples {
background: #40c9c6;
}
}
}
}
}
</style>