feat(Layout): Add classic layout
This commit is contained in:
parent
958edefe7b
commit
839b6015b8
|
@ -14,5 +14,6 @@
|
||||||
"i18n-ally.enabledParsers": ["ts"],
|
"i18n-ally.enabledParsers": ["ts"],
|
||||||
"i18n-ally.sourceLanguage": "en",
|
"i18n-ally.sourceLanguage": "en",
|
||||||
"i18n-ally.displayLanguage": "zh-CN",
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
"i18n-ally.enabledFrameworks": ["vue", "react"]
|
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||||
|
"god.tsconfig": "./tsconfig.json"
|
||||||
}
|
}
|
||||||
|
|
19
src/App.vue
19
src/App.vue
|
@ -6,7 +6,9 @@ import { isDark } from '@/utils/is'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
const size = computed(() => appStore.size)
|
const currentSize = computed(() => appStore.getCurrentSize)
|
||||||
|
|
||||||
|
const greyMode = computed(() => appStore.getGreyMode)
|
||||||
|
|
||||||
const initDark = () => {
|
const initDark = () => {
|
||||||
const isDarkTheme = isDark()
|
const isDarkTheme = isDark()
|
||||||
|
@ -17,12 +19,14 @@ initDark()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ConfigGlobal :size="size">
|
<ConfigGlobal :size="currentSize">
|
||||||
<RouterView />
|
<RouterView :class="{ 'v-grey__mode': greyMode }" />
|
||||||
</ConfigGlobal>
|
</ConfigGlobal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
@prefix-cls: ~'@{namespace}-grey';
|
||||||
|
|
||||||
.size {
|
.size {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -39,4 +43,13 @@ body {
|
||||||
.size;
|
.size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.@{prefix-cls}__mode {
|
||||||
|
-webkit-filter: grayscale(100%);
|
||||||
|
-moz-filter: grayscale(100%);
|
||||||
|
-ms-filter: grayscale(100%);
|
||||||
|
-o-filter: grayscale(100%);
|
||||||
|
filter: grayscale(100%);
|
||||||
|
filter: progid:dximagetransform.microsoft.basicimage(grayscale=1);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -2,13 +2,18 @@
|
||||||
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
||||||
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
// import { compile } from 'path-to-regexp'
|
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { usePermissionStore } from '@/store/modules/permission'
|
||||||
import { filterBreadcrumb } from './helper'
|
import { filterBreadcrumb } from './helper'
|
||||||
import { filter, treeToList } from '@/utils/tree'
|
import { filter, treeToList } from '@/utils/tree'
|
||||||
import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { Icon } from '@/components/Icon'
|
import { Icon } from '@/components/Icon'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
// 面包屑图标
|
||||||
|
const breadcrumbIcon = computed(() => appStore.getBreadcrumbIcon)
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Breadcrumb',
|
name: 'Breadcrumb',
|
||||||
|
@ -41,7 +46,7 @@ export default defineComponent({
|
||||||
const meta = v.meta as RouteMeta
|
const meta = v.meta as RouteMeta
|
||||||
return (
|
return (
|
||||||
<ElBreadcrumbItem to={{ path: disabled ? '' : v.path }} key={v.name}>
|
<ElBreadcrumbItem to={{ path: disabled ? '' : v.path }} key={v.name}>
|
||||||
{meta?.icon ? (
|
{meta?.icon && breadcrumbIcon.value ? (
|
||||||
<>
|
<>
|
||||||
<Icon icon={meta.icon} class="mr-[5px]"></Icon> {t(v?.meta?.title)}
|
<Icon icon={meta.icon} class="mr-[5px]"></Icon> {t(v?.meta?.title)}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import ColorRadioPicker from './src/ColorRadioPicker.vue'
|
||||||
|
|
||||||
|
export { ColorRadioPicker }
|
|
@ -0,0 +1,60 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType, watch, unref, ref } from 'vue'
|
||||||
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
schema: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
modelValue: propTypes.string.def('')
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
|
|
||||||
|
const colorVal = ref(props.modelValue)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val: string) => {
|
||||||
|
if (val === unref(colorVal)) return
|
||||||
|
colorVal.value = val
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听
|
||||||
|
watch(
|
||||||
|
() => colorVal.value,
|
||||||
|
(val: string) => {
|
||||||
|
emit('update:modelValue', val)
|
||||||
|
emit('change', val)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="v-color-radio-picker 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="{ 'is-active': colorVal === item }"
|
||||||
|
:style="{
|
||||||
|
background: item
|
||||||
|
}"
|
||||||
|
@click="colorVal = item"
|
||||||
|
>
|
||||||
|
<Icon v-if="colorVal === item" color="#fff" icon="ep:check" :size="16" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@prefix-cls: ~'@{namespace}-color-radio-picker';
|
||||||
|
|
||||||
|
.@{prefix-cls} {
|
||||||
|
.is-active {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { provide, computed, watch } from 'vue'
|
import { provide, computed, watch, onMounted } from 'vue'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { ElConfigProvider } from 'element-plus'
|
import { ElConfigProvider } from 'element-plus'
|
||||||
import { useLocaleStore } from '@/store/modules/locale'
|
import { useLocaleStore } from '@/store/modules/locale'
|
||||||
|
@ -9,8 +9,20 @@ import { setCssVar } from '@/utils'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
size: propTypes.oneOf<ElememtPlusSzie[]>(['default', 'small', 'large']).def('default')
|
||||||
|
})
|
||||||
|
|
||||||
|
provide('configGlobal', props)
|
||||||
|
|
||||||
|
// 初始化所有主题色
|
||||||
|
onMounted(() => {
|
||||||
|
appStore.setCssVarTheme()
|
||||||
|
})
|
||||||
|
|
||||||
const { width } = useWindowSize()
|
const { width } = useWindowSize()
|
||||||
|
|
||||||
|
// 监听窗口变化
|
||||||
watch(
|
watch(
|
||||||
() => width.value,
|
() => width.value,
|
||||||
(width: number) => {
|
(width: number) => {
|
||||||
|
@ -29,19 +41,14 @@ watch(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 多语言相关
|
||||||
const localeStore = useLocaleStore()
|
const localeStore = useLocaleStore()
|
||||||
|
|
||||||
const locale = computed(() => localeStore.locale)
|
const currentLocale = computed(() => localeStore.currentLocale)
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
size: propTypes.oneOf<ElememtPlusSzie[]>(['default', 'small', 'large']).def('default')
|
|
||||||
})
|
|
||||||
|
|
||||||
provide('configGlobal', props)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ElConfigProvider :locale="locale.elLocale" :message="{ max: 1 }" :size="size">
|
<ElConfigProvider :locale="currentLocale.elLocale" :message="{ max: 1 }" :size="size">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ElConfigProvider>
|
</ElConfigProvider>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,13 +8,13 @@ const localeStore = useLocaleStore()
|
||||||
|
|
||||||
const langMap = computed(() => localeStore.getLocaleMap)
|
const langMap = computed(() => localeStore.getLocaleMap)
|
||||||
|
|
||||||
const currentLang = computed(() => localeStore.getLocale)
|
const currentLang = computed(() => localeStore.getCurrentLocale)
|
||||||
|
|
||||||
const setLang = (lang: LocaleType) => {
|
const setLang = (lang: LocaleType) => {
|
||||||
if (lang === unref(currentLang).lang) return
|
if (lang === unref(currentLang).lang) return
|
||||||
// 需要重新加载页面让整个语言多初始化
|
// 需要重新加载页面让整个语言多初始化
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
localeStore.setLocale({
|
localeStore.setCurrentLocale({
|
||||||
lang
|
lang
|
||||||
})
|
})
|
||||||
const { changeLocale } = useLocale()
|
const { changeLocale } = useLocale()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, computed } from 'vue'
|
import { ref, watch, computed, onMounted, unref } from 'vue'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
@ -12,6 +12,10 @@ const layout = computed(() => appStore.getLayout)
|
||||||
|
|
||||||
const collapse = computed(() => appStore.getCollapse)
|
const collapse = computed(() => appStore.getCollapse)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (unref(collapse)) show.value = false
|
||||||
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => collapse.value,
|
() => collapse.value,
|
||||||
(collapse: boolean) => {
|
(collapse: boolean) => {
|
||||||
|
@ -37,7 +41,7 @@ watch(
|
||||||
{
|
{
|
||||||
'v-logo__Top': layout !== 'classic'
|
'v-logo__Top': layout !== 'classic'
|
||||||
},
|
},
|
||||||
'flex h-[var(--logo-height)] items-center cursor-pointer pl-8px'
|
'flex h-[var(--logo-height)] items-center cursor-pointer pl-8px relative'
|
||||||
]"
|
]"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
|
@ -50,3 +54,18 @@ watch(
|
||||||
}}</div>
|
}}</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@prefix-cls: ~'@{namespace}-logo';
|
||||||
|
|
||||||
|
.@{prefix-cls} {
|
||||||
|
&:after {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid var(--logo-border-color);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -14,6 +14,9 @@ export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
// logo
|
||||||
|
const logo = computed(() => appStore.logo)
|
||||||
|
|
||||||
const { push, currentRoute } = useRouter()
|
const { push, currentRoute } = useRouter()
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const permissionStore = usePermissionStore()
|
||||||
|
@ -61,8 +64,8 @@ export default defineComponent({
|
||||||
'bg-[var(--left-menu-bg-color)]'
|
'bg-[var(--left-menu-bg-color)]'
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Logo></Logo>
|
{logo.value ? <Logo></Logo> : undefined}
|
||||||
<ElScrollbar class={[{ '!h-[calc(100%-var(--top-tool-height))]': true }]}>
|
<ElScrollbar class={[{ '!h-[calc(100%-var(--logo-height))]': logo.value }]}>
|
||||||
<ElMenu
|
<ElMenu
|
||||||
defaultActive={unref(activeMenu)}
|
defaultActive={unref(activeMenu)}
|
||||||
mode={unref(menuMode)}
|
mode={unref(menuMode)}
|
||||||
|
@ -89,9 +92,28 @@ export default defineComponent({
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@prefix-cls: ~'@{namespace}-menu';
|
@prefix-cls: ~'@{namespace}-menu';
|
||||||
|
|
||||||
|
.is-active--after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 4px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--el-color-primary);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
.@{prefix-cls} {
|
.@{prefix-cls} {
|
||||||
transition: width var(--transition-time-02);
|
transition: width var(--transition-time-02);
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100%;
|
||||||
|
border-left: 1px solid var(--left-menu-border-color);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-menu) {
|
:deep(.el-menu) {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
@ -123,6 +145,14 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
.is-active--after;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 设置子菜单的背景颜色
|
// 设置子菜单的背景颜色
|
||||||
.el-menu {
|
.el-menu {
|
||||||
.el-sub-menu__title,
|
.el-sub-menu__title,
|
||||||
|
@ -138,7 +168,12 @@ export default defineComponent({
|
||||||
|
|
||||||
& > .is-active,
|
& > .is-active,
|
||||||
& > .is-active > .el-sub-menu__title {
|
& > .is-active > .el-sub-menu__title {
|
||||||
|
position: relative;
|
||||||
background-color: var(--left-menu-collapse-bg-active-color) !important;
|
background-color: var(--left-menu-collapse-bg-active-color) !important;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
.is-active--after;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +190,16 @@ export default defineComponent({
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@prefix-cls: ~'@{namespace}-menu-popper';
|
@prefix-cls: ~'@{namespace}-menu-popper';
|
||||||
|
|
||||||
|
.is-active--after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 4px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--el-color-primary);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
.@{prefix-cls} {
|
.@{prefix-cls} {
|
||||||
&--vertical {
|
&--vertical {
|
||||||
// 设置选中时子标题的颜色
|
// 设置选中时子标题的颜色
|
||||||
|
@ -175,11 +220,16 @@ export default defineComponent({
|
||||||
|
|
||||||
// 设置选中时的高亮背景
|
// 设置选中时的高亮背景
|
||||||
.el-menu-item.is-active {
|
.el-menu-item.is-active {
|
||||||
|
position: relative;
|
||||||
background-color: var(--left-menu-bg-active-color) !important;
|
background-color: var(--left-menu-bg-active-color) !important;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--left-menu-bg-active-color) !important;
|
background-color: var(--left-menu-bg-active-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
.is-active--after;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,64 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ElDrawer } from 'element-plus'
|
import { ElDrawer, ElDivider } from 'element-plus'
|
||||||
import { ref } from 'vue'
|
import { ref, unref } from 'vue'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { ThemeSwitch } from '@/components/ThemeSwitch'
|
||||||
|
import { ColorRadioPicker } from '@/components/ColorRadioPicker'
|
||||||
|
import { colorIsDark, lighten, hexToRGB } from '@/utils/color'
|
||||||
|
import { useCssVar } from '@vueuse/core'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
import { trim, setCssVar } from '@/utils'
|
||||||
|
import InterfaceDisplay from './components/InterfaceDisplay.vue'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
const drawer = ref(false)
|
const drawer = ref(false)
|
||||||
|
|
||||||
|
// 主题色相关
|
||||||
|
const systemTheme = ref(appStore.getTheme.elColorPrimary)
|
||||||
|
|
||||||
|
const setSystemTheme = (color: string) => {
|
||||||
|
setCssVar('--el-color-primary', color)
|
||||||
|
appStore.setTheme({ elColorPrimary: color })
|
||||||
|
const leftMenuBgColor = useCssVar('--left-menu-bg-color', document.documentElement)
|
||||||
|
setMenuTheme(trim(unref(leftMenuBgColor)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单主题相关
|
||||||
|
const menuTheme = ref(appStore.getTheme.leftMenuBgColor)
|
||||||
|
|
||||||
|
const setMenuTheme = (color: string) => {
|
||||||
|
const primaryColor = useCssVar('--el-color-primary', document.documentElement)
|
||||||
|
const isDarkColor = colorIsDark(color)
|
||||||
|
const theme: Recordable = {
|
||||||
|
// 左侧菜单边框颜色
|
||||||
|
leftMenuBorderColor: isDarkColor ? 'inherit' : '#eee',
|
||||||
|
// 左侧菜单背景颜色
|
||||||
|
leftMenuBgColor: color,
|
||||||
|
// 左侧菜单浅色背景颜色
|
||||||
|
leftMenuBgLightColor: isDarkColor ? lighten(color!, 6) : color,
|
||||||
|
// 左侧菜单选中背景颜色
|
||||||
|
leftMenuBgActiveColor: isDarkColor
|
||||||
|
? 'var(--el-color-primary)'
|
||||||
|
: hexToRGB(unref(primaryColor), 0.1),
|
||||||
|
// 左侧菜单收起选中背景颜色
|
||||||
|
leftMenuCollapseBgActiveColor: isDarkColor
|
||||||
|
? 'var(--el-color-primary)'
|
||||||
|
: hexToRGB(unref(primaryColor), 0.1),
|
||||||
|
// 左侧菜单字体颜色
|
||||||
|
leftMenuTextColor: isDarkColor ? '#bfcbd9' : '#333',
|
||||||
|
// 左侧菜单选中字体颜色
|
||||||
|
leftMenuTextActiveColor: isDarkColor ? '#fff' : 'var(--el-color-primary)',
|
||||||
|
// logo字体颜色
|
||||||
|
logoTitleTextColor: isDarkColor ? '#fff' : 'inherit',
|
||||||
|
// logo边框颜色
|
||||||
|
logoBorderColor: isDarkColor ? 'inherit' : '#eee'
|
||||||
|
}
|
||||||
|
appStore.setTheme(theme)
|
||||||
|
appStore.setCssVarTheme()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -13,7 +69,58 @@ const drawer = ref(false)
|
||||||
<Icon icon="ant-design:setting-outlined" color="#fff" />
|
<Icon icon="ant-design:setting-outlined" color="#fff" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ElDrawer v-model="drawer" :with-header="false" direction="rtl" size="300px">ddd</ElDrawer>
|
<ElDrawer v-model="drawer" direction="rtl" size="350px">
|
||||||
|
<template #title>
|
||||||
|
<span class="text-16px font-700">{{ t('setting.projectSetting') }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<!-- 主题 -->
|
||||||
|
<ElDivider>{{ t('setting.theme') }}</ElDivider>
|
||||||
|
<ThemeSwitch />
|
||||||
|
|
||||||
|
<!-- 布局 -->
|
||||||
|
<ElDivider>{{ t('setting.layout') }}</ElDivider>
|
||||||
|
|
||||||
|
<!-- 系统主题 -->
|
||||||
|
<ElDivider>{{ t('setting.systemTheme') }}</ElDivider>
|
||||||
|
<ColorRadioPicker
|
||||||
|
v-model="systemTheme"
|
||||||
|
:schema="[
|
||||||
|
'#409eff',
|
||||||
|
'#009688',
|
||||||
|
'#536dfe',
|
||||||
|
'#ff5c93',
|
||||||
|
'#ee4f12',
|
||||||
|
'#0096c7',
|
||||||
|
'#9c27b0',
|
||||||
|
'#ff9800'
|
||||||
|
]"
|
||||||
|
@change="setSystemTheme"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 菜单主题 -->
|
||||||
|
<ElDivider>{{ t('setting.menuTheme') }}</ElDivider>
|
||||||
|
<ColorRadioPicker
|
||||||
|
v-model="menuTheme"
|
||||||
|
:schema="[
|
||||||
|
'#fff',
|
||||||
|
'#001529',
|
||||||
|
'#212121',
|
||||||
|
'#273352',
|
||||||
|
'#191b24',
|
||||||
|
'#383f45',
|
||||||
|
'#001628',
|
||||||
|
'#344058'
|
||||||
|
]"
|
||||||
|
@change="setMenuTheme"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 界面显示 -->
|
||||||
|
<ElDivider>{{ t('setting.interfaceDisplay') }}</ElDivider>
|
||||||
|
<InterfaceDisplay />
|
||||||
|
</ElDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElSwitch } from 'element-plus'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
// 面包屑
|
||||||
|
const breadcrumb = ref(appStore.getBreadcrumb)
|
||||||
|
|
||||||
|
const breadcrumbChange = (show: boolean) => {
|
||||||
|
appStore.setBreadcrumb(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 面包屑图标
|
||||||
|
const breadcrumbIcon = ref(appStore.getBreadcrumbIcon)
|
||||||
|
|
||||||
|
const breadcrumbIconChange = (show: boolean) => {
|
||||||
|
appStore.setBreadcrumbIcon(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 折叠菜单
|
||||||
|
const collapse = ref(appStore.getCollapse)
|
||||||
|
|
||||||
|
const collapseChange = (show: boolean) => {
|
||||||
|
appStore.setCollapse(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 折叠图标
|
||||||
|
const hamburger = ref(appStore.getHamburger)
|
||||||
|
|
||||||
|
const hamburgerChange = (show: boolean) => {
|
||||||
|
appStore.setHamburger(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏图标
|
||||||
|
const screenfull = ref(appStore.getScreenfull)
|
||||||
|
|
||||||
|
const screenfullChange = (show: boolean) => {
|
||||||
|
appStore.setScreenfull(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尺寸图标
|
||||||
|
const size = ref(appStore.getSize)
|
||||||
|
|
||||||
|
const sizeChange = (show: boolean) => {
|
||||||
|
appStore.setSize(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多语言图标
|
||||||
|
const locale = ref(appStore.getLocale)
|
||||||
|
|
||||||
|
const localeChange = (show: boolean) => {
|
||||||
|
appStore.setLocale(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签页
|
||||||
|
const tagsView = ref(appStore.getTagsView)
|
||||||
|
|
||||||
|
const tagsViewChange = (show: boolean) => {
|
||||||
|
appStore.setTagsView(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// logo
|
||||||
|
const logo = ref(appStore.getLogo)
|
||||||
|
|
||||||
|
const logoChange = (show: boolean) => {
|
||||||
|
appStore.setLogo(show)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 灰色模式
|
||||||
|
const greyMode = ref(appStore.getGreyMode)
|
||||||
|
|
||||||
|
const greyModeChange = (show: boolean) => {
|
||||||
|
appStore.setGreyMode(show)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="v-interface-display">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.breadcrumb') }}</span>
|
||||||
|
<ElSwitch v-model="breadcrumb" @change="breadcrumbChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.breadcrumbIcon') }}</span>
|
||||||
|
<ElSwitch v-model="breadcrumbIcon" @change="breadcrumbIconChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.collapseMenu') }}</span>
|
||||||
|
<ElSwitch v-model="collapse" @change="collapseChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.hamburgerIcon') }}</span>
|
||||||
|
<ElSwitch v-model="hamburger" @change="hamburgerChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.screenfullIcon') }}</span>
|
||||||
|
<ElSwitch v-model="screenfull" @change="screenfullChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.sizeIcon') }}</span>
|
||||||
|
<ElSwitch v-model="size" @change="sizeChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.localeIcon') }}</span>
|
||||||
|
<ElSwitch v-model="locale" @change="localeChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.tagsView') }}</span>
|
||||||
|
<ElSwitch v-model="tagsView" @change="tagsViewChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.logo') }}</span>
|
||||||
|
<ElSwitch v-model="logo" @change="logoChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.greyMode') }}</span>
|
||||||
|
<ElSwitch v-model="greyMode" @change="greyModeChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -9,13 +9,13 @@ const appStore = useAppStore()
|
||||||
|
|
||||||
const sizeMap = computed(() => appStore.sizeMap)
|
const sizeMap = computed(() => appStore.sizeMap)
|
||||||
|
|
||||||
const setSize = (size: ElememtPlusSzie) => {
|
const setCurrentSize = (size: ElememtPlusSzie) => {
|
||||||
appStore.setSize(size)
|
appStore.setCurrentSize(size)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ElDropdown trigger="click" @command="setSize">
|
<ElDropdown trigger="click" @command="setCurrentSize">
|
||||||
<Icon
|
<Icon
|
||||||
:size="18"
|
:size="18"
|
||||||
icon="mdi:format-size"
|
icon="mdi:format-size"
|
||||||
|
|
|
@ -127,7 +127,7 @@ watch(
|
||||||
<template>
|
<template>
|
||||||
<div class="v-tags-view h-[var(--tags-view-height)] flex w-full">
|
<div class="v-tags-view h-[var(--tags-view-height)] flex w-full">
|
||||||
<span class="v-tags-view__tool w-[40px] h-[40px] text-center leading-[40px] cursor-pointer">
|
<span class="v-tags-view__tool w-[40px] h-[40px] text-center leading-[40px] cursor-pointer">
|
||||||
<Icon icon="ant-design:left-outlined" color="#333" />
|
<Icon icon="ep:d-arrow-left" color="#333" />
|
||||||
</span>
|
</span>
|
||||||
<div class="overflow-hidden flex-1">
|
<div class="overflow-hidden flex-1">
|
||||||
<ElScrollbar>
|
<ElScrollbar>
|
||||||
|
@ -216,7 +216,7 @@ watch(
|
||||||
</ElScrollbar>
|
</ElScrollbar>
|
||||||
</div>
|
</div>
|
||||||
<span class="v-tags-view__tool w-[40px] h-[40px] text-center leading-[40px] cursor-pointer">
|
<span class="v-tags-view__tool w-[40px] h-[40px] text-center leading-[40px] cursor-pointer">
|
||||||
<Icon icon="ant-design:right-outlined" color="#333" />
|
<Icon icon="ep:d-arrow-right" color="#333" />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="v-tags-view__tool w-[40px] h-[40px] text-center leading-[40px] cursor-pointer"
|
class="v-tags-view__tool w-[40px] h-[40px] text-center leading-[40px] cursor-pointer"
|
||||||
|
|
|
@ -5,47 +5,68 @@ const { wsCache } = useCache()
|
||||||
export type LayoutType = 'classic' | 'leftTop' | 'top' | 'test'
|
export type LayoutType = 'classic' | 'leftTop' | 'top' | 'test'
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
|
breadcrumb: boolean
|
||||||
|
breadcrumbIcon: boolean
|
||||||
collapse: boolean
|
collapse: boolean
|
||||||
showTags: boolean
|
hamburger: boolean
|
||||||
showLogo: boolean
|
screenfull: boolean
|
||||||
showNavbar: boolean
|
size: boolean
|
||||||
fixedHeader: boolean
|
locale: boolean
|
||||||
|
tagsView: boolean
|
||||||
|
logo: boolean
|
||||||
|
greyMode: boolean
|
||||||
|
|
||||||
layout: LayoutType
|
layout: LayoutType
|
||||||
showBreadcrumb: boolean
|
|
||||||
showHamburger: boolean
|
|
||||||
showScreenfull: boolean
|
|
||||||
showUserInfo: boolean
|
|
||||||
title: string
|
title: string
|
||||||
logoTitle: string
|
logoTitle: string
|
||||||
userInfo: string
|
userInfo: string
|
||||||
greyMode: boolean
|
|
||||||
showBackTop: boolean
|
|
||||||
showMenuTab: boolean
|
|
||||||
isDark: boolean
|
isDark: boolean
|
||||||
size: ElememtPlusSzie
|
currentSize: ElememtPlusSzie
|
||||||
sizeMap: ElememtPlusSzie[]
|
sizeMap: ElememtPlusSzie[]
|
||||||
mobile: boolean
|
mobile: boolean
|
||||||
|
theme: Recordable
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appModules: AppState = {
|
export const appModules: AppState = {
|
||||||
collapse: false, // 菜单栏是否栏缩收
|
breadcrumb: true, // 面包屑
|
||||||
showLogo: true, // 是否显示logo
|
breadcrumbIcon: true, // 面包屑图标
|
||||||
showTags: true, // 是否显示标签栏
|
collapse: false, // 折叠菜单
|
||||||
showNavbar: true, // 是否显示navbar
|
hamburger: true, // 折叠图标
|
||||||
fixedHeader: true, // 是否固定header
|
screenfull: true, // 全屏图标
|
||||||
|
size: true, // 尺寸图标
|
||||||
|
locale: true, // 多语言图标
|
||||||
|
tagsView: true, // 标签页
|
||||||
|
logo: true, // logo
|
||||||
|
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
||||||
|
|
||||||
layout: 'classic', // layout布局
|
layout: 'classic', // layout布局
|
||||||
showBreadcrumb: true, // 是否显示面包屑
|
|
||||||
showHamburger: true, // 是否显示侧边栏缩收按钮
|
|
||||||
showScreenfull: true, // 是否全屏按钮
|
|
||||||
showUserInfo: true, // 是否显示用户头像
|
|
||||||
title: 'butterfly-admin', // 标题
|
title: 'butterfly-admin', // 标题
|
||||||
logoTitle: 'ButterflyAdmin', // logo标题
|
logoTitle: 'ButterflyAdmin', // logo标题
|
||||||
userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
|
userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
|
||||||
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
|
||||||
showBackTop: true, // 是否显示回到顶部
|
|
||||||
showMenuTab: false, // 是否固定一级菜单
|
|
||||||
isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
|
isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
|
||||||
size: wsCache.get('default') || 'default', // 组件尺寸
|
currentSize: wsCache.get('default') || 'default', // 组件尺寸
|
||||||
sizeMap: ['default', 'large', 'small'],
|
sizeMap: ['default', 'large', 'small'],
|
||||||
mobile: false // 是否是移动端
|
mobile: false, // 是否是移动端
|
||||||
|
theme: wsCache.get('theme') || {
|
||||||
|
// 主题色
|
||||||
|
elColorPrimary: '#409eff',
|
||||||
|
// 左侧菜单边框颜色
|
||||||
|
leftMenuBorderColor: 'inherit',
|
||||||
|
// 左侧菜单背景颜色
|
||||||
|
leftMenuBgColor: '#001529',
|
||||||
|
// 左侧菜单浅色背景颜色
|
||||||
|
leftMenuBgLightColor: '#0f2438',
|
||||||
|
// 左侧菜单选中背景颜色
|
||||||
|
leftMenuBgActiveColor: 'var(--el-color-primary)',
|
||||||
|
// 左侧菜单收起选中背景颜色
|
||||||
|
leftMenuCollapseBgActiveColor: 'var(--el-color-primary)',
|
||||||
|
// 左侧菜单字体颜色
|
||||||
|
leftMenuTextColor: '#bfcbd9',
|
||||||
|
// 左侧菜单选中字体颜色
|
||||||
|
leftMenuTextActiveColor: '#fff',
|
||||||
|
// logo字体颜色
|
||||||
|
logoTitleTextColor: '#fff',
|
||||||
|
// logo边框颜色
|
||||||
|
logoBorderColor: 'inherit'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,13 @@ export const elLocaleMap = {
|
||||||
'zh-CN': zhCn,
|
'zh-CN': zhCn,
|
||||||
en: en
|
en: en
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LocaleState {
|
export interface LocaleState {
|
||||||
locale: LocaleDropdownType
|
currentLocale: LocaleDropdownType
|
||||||
localeMap: LocaleDropdownType[]
|
localeMap: LocaleDropdownType[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const localeModules: LocaleState = {
|
export const localeModules: LocaleState = {
|
||||||
locale: {
|
currentLocale: {
|
||||||
lang: wsCache.get('lang') || 'zh-CN',
|
lang: wsCache.get('lang') || 'zh-CN',
|
||||||
elLocale: elLocaleMap[wsCache.get('lang') || 'zh-CN']
|
elLocale: elLocaleMap[wsCache.get('lang') || 'zh-CN']
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,7 @@ const setI18nLanguage = (locale: LocaleType) => {
|
||||||
} else {
|
} else {
|
||||||
;(i18n.global.locale as any).value = locale
|
;(i18n.global.locale as any).value = locale
|
||||||
}
|
}
|
||||||
localeStore.setLocale({
|
localeStore.setCurrentLocale({
|
||||||
lang: locale
|
lang: locale
|
||||||
})
|
})
|
||||||
setHtmlPageLang(locale)
|
setHtmlPageLang(locale)
|
||||||
|
|
|
@ -15,10 +15,30 @@ import AppView from './components/AppView.vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
// 是否是移动端
|
||||||
const mobile = computed(() => appStore.getMobile)
|
const mobile = computed(() => appStore.getMobile)
|
||||||
|
|
||||||
|
// 面包屑
|
||||||
|
const breadcrumb = computed(() => appStore.getBreadcrumb)
|
||||||
|
|
||||||
|
// 菜单折叠
|
||||||
const collapse = computed(() => appStore.getCollapse)
|
const collapse = computed(() => appStore.getCollapse)
|
||||||
|
|
||||||
|
// 折叠图标
|
||||||
|
const hamburger = computed(() => appStore.getHamburger)
|
||||||
|
|
||||||
|
// 全屏图标
|
||||||
|
const screenfull = computed(() => appStore.getScreenfull)
|
||||||
|
|
||||||
|
// 尺寸图标
|
||||||
|
const size = computed(() => appStore.getSize)
|
||||||
|
|
||||||
|
// 多语言图标
|
||||||
|
const locale = computed(() => appStore.getLocale)
|
||||||
|
|
||||||
|
// 标签页
|
||||||
|
const tagsView = computed(() => appStore.getTagsView)
|
||||||
|
|
||||||
const classSuffix = computed(() => appStore.getLayout)
|
const classSuffix = computed(() => appStore.getLayout)
|
||||||
|
|
||||||
const handleClickOutside = () => {
|
const handleClickOutside = () => {
|
||||||
|
@ -57,19 +77,22 @@ export default defineComponent({
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<div class="h-full flex items-center">
|
<div class="h-full flex items-center">
|
||||||
<Collapse class="header__tigger"></Collapse>
|
{hamburger.value ? <Collapse class="header__tigger"></Collapse> : undefined}
|
||||||
<Breadcrumb class="<md:hidden"></Breadcrumb>
|
{breadcrumb.value ? <Breadcrumb class="<md:hidden"></Breadcrumb> : undefined}
|
||||||
</div>
|
</div>
|
||||||
<div class="h-full flex items-center">
|
<div class="h-full flex items-center">
|
||||||
<Screenfull class="header__tigger"></Screenfull>
|
{screenfull.value ? <Screenfull class="header__tigger"></Screenfull> : undefined}
|
||||||
<SizeDropdown class="header__tigger"></SizeDropdown>
|
{size.value ? <SizeDropdown class="header__tigger"></SizeDropdown> : undefined}
|
||||||
<LocaleDropdown class="header__tigger"></LocaleDropdown>
|
{locale.value ? <LocaleDropdown class="header__tigger"></LocaleDropdown> : undefined}
|
||||||
<UserInfo class="header__tigger"></UserInfo>
|
<UserInfo class="header__tigger"></UserInfo>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{tagsView.value ? (
|
||||||
<div class="v-app-right__tags-view relative">
|
<div class="v-app-right__tags-view relative">
|
||||||
<TagsView></TagsView>
|
<TagsView></TagsView>
|
||||||
</div>
|
</div>
|
||||||
|
) : undefined}
|
||||||
|
|
||||||
<AppView></AppView>
|
<AppView></AppView>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,24 @@ export default {
|
||||||
closeOther: 'Close other',
|
closeOther: 'Close other',
|
||||||
closeAll: 'Close all'
|
closeAll: 'Close all'
|
||||||
},
|
},
|
||||||
|
setting: {
|
||||||
|
projectSetting: 'Project setting',
|
||||||
|
theme: 'Theme',
|
||||||
|
layout: 'Layout',
|
||||||
|
systemTheme: 'System theme',
|
||||||
|
menuTheme: 'Menu theme',
|
||||||
|
interfaceDisplay: 'Interface display',
|
||||||
|
breadcrumb: 'Breadcrumb',
|
||||||
|
breadcrumbIcon: 'Breadcrumb icon',
|
||||||
|
collapseMenu: 'Collapse menu',
|
||||||
|
hamburgerIcon: 'Hamburger icon',
|
||||||
|
screenfullIcon: 'Screenfull icon',
|
||||||
|
sizeIcon: 'Size icon',
|
||||||
|
localeIcon: 'Locale icon',
|
||||||
|
tagsView: 'Tags view',
|
||||||
|
logo: 'Logo',
|
||||||
|
greyMode: 'Grey mode'
|
||||||
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'Default',
|
default: 'Default',
|
||||||
large: 'Large',
|
large: 'Large',
|
||||||
|
@ -46,9 +64,6 @@ export default {
|
||||||
menu12: 'Menu1-2',
|
menu12: 'Menu1-2',
|
||||||
menu2: 'Menu2'
|
menu2: 'Menu2'
|
||||||
},
|
},
|
||||||
mock: {
|
|
||||||
loginErr: 'Wrong account or password'
|
|
||||||
},
|
|
||||||
formDemo: {
|
formDemo: {
|
||||||
input: 'Input',
|
input: 'Input',
|
||||||
inputNumber: 'InputNumber',
|
inputNumber: 'InputNumber',
|
||||||
|
|
|
@ -19,6 +19,24 @@ export default {
|
||||||
closeOther: '关闭其他标签页',
|
closeOther: '关闭其他标签页',
|
||||||
closeAll: '关闭全部标签页'
|
closeAll: '关闭全部标签页'
|
||||||
},
|
},
|
||||||
|
setting: {
|
||||||
|
projectSetting: '项目配置',
|
||||||
|
theme: '主题',
|
||||||
|
layout: '布局',
|
||||||
|
systemTheme: '系统主题',
|
||||||
|
menuTheme: '菜单主题',
|
||||||
|
interfaceDisplay: '界面显示',
|
||||||
|
breadcrumb: '面包屑',
|
||||||
|
breadcrumbIcon: '面包屑图标',
|
||||||
|
collapseMenu: '折叠菜单',
|
||||||
|
hamburgerIcon: '折叠图标',
|
||||||
|
screenfullIcon: '全屏图标',
|
||||||
|
sizeIcon: '尺寸图标',
|
||||||
|
localeIcon: '多语言图标',
|
||||||
|
tagsView: '标签页',
|
||||||
|
logo: '标志',
|
||||||
|
greyMode: '灰色模式'
|
||||||
|
},
|
||||||
size: {
|
size: {
|
||||||
default: '默认',
|
default: '默认',
|
||||||
large: '大',
|
large: '大',
|
||||||
|
@ -46,9 +64,6 @@ export default {
|
||||||
menu12: '菜单1-2',
|
menu12: '菜单1-2',
|
||||||
menu2: '菜单2'
|
menu2: '菜单2'
|
||||||
},
|
},
|
||||||
mock: {
|
|
||||||
loginErr: '账号或密码错误'
|
|
||||||
},
|
|
||||||
formDemo: {
|
formDemo: {
|
||||||
input: '输入框',
|
input: '输入框',
|
||||||
inputNumber: '数字输入框',
|
inputNumber: '数字输入框',
|
||||||
|
|
|
@ -8,14 +8,14 @@ export let i18n: ReturnType<typeof createI18n>
|
||||||
|
|
||||||
const createI18nOptions = async (): Promise<I18nOptions> => {
|
const createI18nOptions = async (): Promise<I18nOptions> => {
|
||||||
const localeStore = useLocaleStoreWithOut()
|
const localeStore = useLocaleStoreWithOut()
|
||||||
const locale = localeStore.getLocale
|
const locale = localeStore.getCurrentLocale
|
||||||
const localeMap = localeStore.getLocaleMap
|
const localeMap = localeStore.getLocaleMap
|
||||||
const defaultLocal = await import(`../../locales/${locale.lang}.ts`)
|
const defaultLocal = await import(`../../locales/${locale.lang}.ts`)
|
||||||
const message = defaultLocal.default ?? {}
|
const message = defaultLocal.default ?? {}
|
||||||
|
|
||||||
setHtmlPageLang(locale.lang)
|
setHtmlPageLang(locale.lang)
|
||||||
|
|
||||||
localeStore.setLocale({
|
localeStore.setCurrentLocale({
|
||||||
lang: locale.lang
|
lang: locale.lang
|
||||||
// elLocale: elLocal
|
// elLocale: elLocal
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { store } from '../index'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
import { appModules } from '@/config/app'
|
import { appModules } from '@/config/app'
|
||||||
import type { AppState, LayoutType } from '@/config/app'
|
import type { AppState, LayoutType } from '@/config/app'
|
||||||
|
import { setCssVar, humpToUnderline } from '@/utils'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
|
|
||||||
|
@ -10,36 +11,40 @@ export const useAppStore = defineStore({
|
||||||
id: 'app',
|
id: 'app',
|
||||||
state: (): AppState => appModules,
|
state: (): AppState => appModules,
|
||||||
getters: {
|
getters: {
|
||||||
|
getBreadcrumb(): boolean {
|
||||||
|
return this.breadcrumb
|
||||||
|
},
|
||||||
|
getBreadcrumbIcon(): boolean {
|
||||||
|
return this.breadcrumbIcon
|
||||||
|
},
|
||||||
getCollapse(): boolean {
|
getCollapse(): boolean {
|
||||||
return this.collapse
|
return this.collapse
|
||||||
},
|
},
|
||||||
getShowLogo(): boolean {
|
getHamburger(): boolean {
|
||||||
return this.showLogo
|
return this.hamburger
|
||||||
},
|
},
|
||||||
getShowTags(): boolean {
|
getScreenfull(): boolean {
|
||||||
return this.showTags
|
return this.screenfull
|
||||||
},
|
},
|
||||||
getShowNavbar(): boolean {
|
getSize(): boolean {
|
||||||
return this.showNavbar
|
return this.size
|
||||||
},
|
},
|
||||||
getFixedHeader(): boolean {
|
getLocale(): boolean {
|
||||||
return this.fixedHeader
|
return this.locale
|
||||||
},
|
},
|
||||||
|
getTagsView(): boolean {
|
||||||
|
return this.tagsView
|
||||||
|
},
|
||||||
|
getLogo(): boolean {
|
||||||
|
return this.logo
|
||||||
|
},
|
||||||
|
getGreyMode(): boolean {
|
||||||
|
return this.greyMode
|
||||||
|
},
|
||||||
|
|
||||||
getLayout(): LayoutType {
|
getLayout(): LayoutType {
|
||||||
return this.layout
|
return this.layout
|
||||||
},
|
},
|
||||||
getShowBreadcrumb(): boolean {
|
|
||||||
return this.showBreadcrumb
|
|
||||||
},
|
|
||||||
getShowHamburger(): boolean {
|
|
||||||
return this.showHamburger
|
|
||||||
},
|
|
||||||
getShowScreenfull(): boolean {
|
|
||||||
return this.showScreenfull
|
|
||||||
},
|
|
||||||
getShowUserInfo(): boolean {
|
|
||||||
return this.showUserInfo
|
|
||||||
},
|
|
||||||
getTitle(): string {
|
getTitle(): string {
|
||||||
return this.title
|
return this.title
|
||||||
},
|
},
|
||||||
|
@ -49,74 +54,63 @@ export const useAppStore = defineStore({
|
||||||
getUserInfo(): string {
|
getUserInfo(): string {
|
||||||
return this.userInfo
|
return this.userInfo
|
||||||
},
|
},
|
||||||
getGreyMode(): boolean {
|
|
||||||
return this.greyMode
|
|
||||||
},
|
|
||||||
getShowBackTop(): boolean {
|
|
||||||
return this.showBackTop
|
|
||||||
},
|
|
||||||
getShowMenuTab(): boolean {
|
|
||||||
return this.showMenuTab
|
|
||||||
},
|
|
||||||
getIsDark(): boolean {
|
getIsDark(): boolean {
|
||||||
return this.isDark
|
return this.isDark
|
||||||
},
|
},
|
||||||
getSize(): ElememtPlusSzie {
|
getCurrentSize(): ElememtPlusSzie {
|
||||||
return this.size
|
return this.currentSize
|
||||||
},
|
},
|
||||||
getSizeMap(): ElememtPlusSzie[] {
|
getSizeMap(): ElememtPlusSzie[] {
|
||||||
return this.sizeMap
|
return this.sizeMap
|
||||||
},
|
},
|
||||||
getMobile(): boolean {
|
getMobile(): boolean {
|
||||||
return this.mobile
|
return this.mobile
|
||||||
|
},
|
||||||
|
getTheme(): Recordable {
|
||||||
|
return this.theme
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
setBreadcrumb(breadcrumb: boolean) {
|
||||||
|
this.breadcrumb = breadcrumb
|
||||||
|
},
|
||||||
|
setBreadcrumbIcon(breadcrumbIcon: boolean) {
|
||||||
|
this.breadcrumbIcon = breadcrumbIcon
|
||||||
|
},
|
||||||
setCollapse(collapse: boolean) {
|
setCollapse(collapse: boolean) {
|
||||||
this.collapse = collapse
|
this.collapse = collapse
|
||||||
},
|
},
|
||||||
setShowLogo(showLogo: boolean) {
|
setHamburger(hamburger: boolean) {
|
||||||
this.showLogo = showLogo
|
this.hamburger = hamburger
|
||||||
},
|
},
|
||||||
setShowTags(showTags: boolean) {
|
setScreenfull(screenfull: boolean) {
|
||||||
this.showTags = showTags
|
this.screenfull = screenfull
|
||||||
},
|
},
|
||||||
setShowNavbar(showNavbar: boolean) {
|
setSize(size: boolean) {
|
||||||
this.showNavbar = showNavbar
|
this.size = size
|
||||||
},
|
},
|
||||||
setFixedHeader(fixedHeader: boolean) {
|
setLocale(locale: boolean) {
|
||||||
this.fixedHeader = fixedHeader
|
this.locale = locale
|
||||||
},
|
},
|
||||||
|
setTagsView(tagsView: boolean) {
|
||||||
|
this.tagsView = tagsView
|
||||||
|
},
|
||||||
|
setLogo(logo: boolean) {
|
||||||
|
this.logo = logo
|
||||||
|
},
|
||||||
|
setGreyMode(greyMode: boolean) {
|
||||||
|
this.greyMode = greyMode
|
||||||
|
},
|
||||||
|
|
||||||
setLayout(layout: LayoutType) {
|
setLayout(layout: LayoutType) {
|
||||||
this.layout = layout
|
this.layout = layout
|
||||||
},
|
},
|
||||||
setBreadcrumb(showBreadcrumb: boolean) {
|
|
||||||
this.showBreadcrumb = showBreadcrumb
|
|
||||||
},
|
|
||||||
setHamburger(showHamburger: boolean) {
|
|
||||||
this.showHamburger = showHamburger
|
|
||||||
},
|
|
||||||
setScreenfull(showScreenfull: boolean) {
|
|
||||||
this.showScreenfull = showScreenfull
|
|
||||||
},
|
|
||||||
setUserInfo(showUserInfo: boolean) {
|
|
||||||
this.showUserInfo = showUserInfo
|
|
||||||
},
|
|
||||||
setTitle(title: string) {
|
setTitle(title: string) {
|
||||||
this.title = title
|
this.title = title
|
||||||
},
|
},
|
||||||
setLogoTitle(logoTitle: string) {
|
setLogoTitle(logoTitle: string) {
|
||||||
this.logoTitle = logoTitle
|
this.logoTitle = logoTitle
|
||||||
},
|
},
|
||||||
setGreyMode(greyMode: boolean) {
|
|
||||||
this.greyMode = greyMode
|
|
||||||
},
|
|
||||||
setShowBackTop(showBackTop: boolean) {
|
|
||||||
this.showBackTop = showBackTop
|
|
||||||
},
|
|
||||||
setShowMenuTab(showMenuTab: boolean) {
|
|
||||||
this.showMenuTab = showMenuTab
|
|
||||||
},
|
|
||||||
setIsDark(isDark: boolean) {
|
setIsDark(isDark: boolean) {
|
||||||
this.isDark = isDark
|
this.isDark = isDark
|
||||||
if (this.isDark) {
|
if (this.isDark) {
|
||||||
|
@ -128,12 +122,21 @@ export const useAppStore = defineStore({
|
||||||
}
|
}
|
||||||
wsCache.set('isDark', this.isDark)
|
wsCache.set('isDark', this.isDark)
|
||||||
},
|
},
|
||||||
setSize(size: ElememtPlusSzie) {
|
setCurrentSize(currentSize: ElememtPlusSzie) {
|
||||||
this.size = size
|
this.currentSize = currentSize
|
||||||
wsCache.set('size', this.size)
|
wsCache.set('currentSize', this.currentSize)
|
||||||
},
|
},
|
||||||
setMobile(mobile: boolean) {
|
setMobile(mobile: boolean) {
|
||||||
this.mobile = mobile
|
this.mobile = mobile
|
||||||
|
},
|
||||||
|
setTheme(theme: Recordable) {
|
||||||
|
this.theme = Object.assign(this.theme, theme)
|
||||||
|
wsCache.set('theme', this.theme)
|
||||||
|
},
|
||||||
|
setCssVarTheme() {
|
||||||
|
for (const key in this.theme) {
|
||||||
|
setCssVar(`--${humpToUnderline(key)}`, this.theme[key])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,18 +10,18 @@ export const useLocaleStore = defineStore({
|
||||||
id: 'locales',
|
id: 'locales',
|
||||||
state: (): LocaleState => localeModules,
|
state: (): LocaleState => localeModules,
|
||||||
getters: {
|
getters: {
|
||||||
getLocale(): LocaleDropdownType {
|
getCurrentLocale(): LocaleDropdownType {
|
||||||
return this.locale
|
return this.currentLocale
|
||||||
},
|
},
|
||||||
getLocaleMap(): LocaleDropdownType[] {
|
getLocaleMap(): LocaleDropdownType[] {
|
||||||
return this.localeMap
|
return this.localeMap
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setLocale(localeMap: LocaleDropdownType) {
|
setCurrentLocale(localeMap: LocaleDropdownType) {
|
||||||
// this.locale = Object.assign(this.locale, localeMap)
|
// this.locale = Object.assign(this.locale, localeMap)
|
||||||
this.locale.lang = localeMap?.lang
|
this.currentLocale.lang = localeMap?.lang
|
||||||
this.locale.elLocale = elLocaleMap[localeMap?.lang]
|
this.currentLocale.elLocale = elLocaleMap[localeMap?.lang]
|
||||||
wsCache.set('lang', localeMap?.lang)
|
wsCache.set('lang', localeMap?.lang)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
--dark-bg-color: #293146;
|
--dark-bg-color: #293146;
|
||||||
|
|
||||||
/* left menu start */
|
/* left menu start */
|
||||||
|
--left-menu-border-color: 'inherit';
|
||||||
|
|
||||||
--left-menu-max-width: 200px;
|
--left-menu-max-width: 200px;
|
||||||
|
|
||||||
--left-menu-min-width: 64px;
|
--left-menu-min-width: 64px;
|
||||||
|
@ -23,10 +25,12 @@
|
||||||
--logo-height: 50px;
|
--logo-height: 50px;
|
||||||
|
|
||||||
--logo-title-text-color: #fff;
|
--logo-title-text-color: #fff;
|
||||||
|
|
||||||
|
--logo-border-color: 'inherit';
|
||||||
/* logo end */
|
/* logo end */
|
||||||
|
|
||||||
/* header start */
|
/* header start */
|
||||||
--top-tool-height: 40px;
|
--top-tool-height: var(--logo-height);
|
||||||
|
|
||||||
--top-tool-p-x: 0;
|
--top-tool-p-x: 0;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ export const rgbToHex = (r: number, g: number, b: number) => {
|
||||||
* @param {string} hex The color to transform
|
* @param {string} hex The color to transform
|
||||||
* @returns The RGB representation of the passed color
|
* @returns The RGB representation of the passed color
|
||||||
*/
|
*/
|
||||||
export const hexToRGB = (hex: string) => {
|
export const hexToRGB = (hex: string, opacity?: number) => {
|
||||||
let sHex = hex.toLowerCase()
|
let sHex = hex.toLowerCase()
|
||||||
if (isHexColor(hex)) {
|
if (isHexColor(hex)) {
|
||||||
if (sHex.length === 4) {
|
if (sHex.length === 4) {
|
||||||
|
@ -44,7 +44,9 @@ export const hexToRGB = (hex: string) => {
|
||||||
for (let i = 1; i < 7; i += 2) {
|
for (let i = 1; i < 7; i += 2) {
|
||||||
sColorChange.push(parseInt('0x' + sHex.slice(i, i + 2)))
|
sColorChange.push(parseInt('0x' + sHex.slice(i, i + 2)))
|
||||||
}
|
}
|
||||||
return 'RGB(' + sColorChange.join(',') + ')'
|
return opacity
|
||||||
|
? 'RGBA(' + sColorChange.join(',') + ',' + opacity + ')'
|
||||||
|
: 'RGB(' + sColorChange.join(',') + ')'
|
||||||
}
|
}
|
||||||
return sHex
|
return sHex
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,3 +59,7 @@ export const findIndex = <T = Recordable>(ary: Array<T>, fn: Fn): number => {
|
||||||
})
|
})
|
||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const trim = (str: string) => {
|
||||||
|
return str.replace(/(^\s*)|(\s*$)/g, '')
|
||||||
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ const { t } = useI18n()
|
||||||
|
|
||||||
<div class="flex justify-end items-center space-x-10px">
|
<div class="flex justify-end items-center space-x-10px">
|
||||||
<ThemeSwitch />
|
<ThemeSwitch />
|
||||||
<LocaleDropdown class="<xl:!text-white dark:!text-white" />
|
<LocaleDropdown class="<xl:text-white dark:text-white" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Transition appear enter-active-class="animate__animated animate__bounceInRight">
|
<Transition appear enter-active-class="animate__animated animate__bounceInRight">
|
||||||
|
|
Loading…
Reference in New Issue