mirror of
https://github.com/zclzone/vue-naive-admin.git
synced 2026-01-22 15:40:21 +08:00
feat: 增加设置主题色功能
This commit is contained in:
11
src/App.vue
11
src/App.vue
@@ -29,8 +29,6 @@
|
||||
<script setup>
|
||||
import { zhCN, dateZhCN, darkTheme } from 'naive-ui'
|
||||
import { LayoutSetting } from '@/components'
|
||||
import { useCssVar } from '@vueuse/core'
|
||||
import { kebabCase } from 'lodash-es'
|
||||
import { useAppStore, useTabStore } from '@/store'
|
||||
|
||||
const layouts = new Map()
|
||||
@@ -50,15 +48,6 @@ const Layout = computed(() => {
|
||||
return getLayout(route.meta?.layout || appStore.layout)
|
||||
})
|
||||
|
||||
function setupCssVar() {
|
||||
const common = appStore.naiveThemeOverrides?.common || {}
|
||||
for (const key in common) {
|
||||
useCssVar(`--${kebabCase(key)}`, document.documentElement).value = common[key] || ''
|
||||
if (key === 'primaryColor') window.localStorage.setItem('__THEME_COLOR__', common[key] || '')
|
||||
}
|
||||
}
|
||||
setupCssVar()
|
||||
|
||||
const tabStore = useTabStore()
|
||||
const keepAliveNames = computed(() => {
|
||||
return tabStore.tabs.filter((item) => item.keepAlive).map((item) => item.name)
|
||||
|
||||
25
src/components/common/ThemeSetting.vue
Normal file
25
src/components/common/ThemeSetting.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-color-picker
|
||||
class="mr-16 h-40 w-80"
|
||||
:value="appStore.primaryColor"
|
||||
:swatches="primaryColors"
|
||||
:on-update:value="(v) => appStore.setPrimaryColor(v)"
|
||||
/>
|
||||
</template>
|
||||
设置主题色
|
||||
</n-tooltip>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPresetColors } from '@arco-design/color'
|
||||
import { useAppStore } from '@/store'
|
||||
const appStore = useAppStore()
|
||||
|
||||
const primaryColors = Object.entries(getPresetColors()).map(([, value]) => value.primary)
|
||||
|
||||
watchEffect(() => {
|
||||
appStore.setThemeColor(appStore.primaryColor, appStore.isDark)
|
||||
})
|
||||
</script>
|
||||
@@ -66,7 +66,7 @@ function handleMenuSelect(key, item) {
|
||||
right: 8px;
|
||||
}
|
||||
&.n-menu-item-content--selected::before {
|
||||
border-left: 4px solid var(--primary-color);
|
||||
border-left: 4px solid rgb(var(--primary-color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<n-tabs
|
||||
:value="tabStore.activeTab"
|
||||
:closable="tabStore.tabs.length > 1"
|
||||
:style="`--selected-bg: ${appStore.isDark ? '#1b2429' : '#eaf0f1'}`"
|
||||
type="card"
|
||||
@close="(path) => tabStore.removeTab(path)"
|
||||
>
|
||||
@@ -38,10 +37,9 @@
|
||||
|
||||
<script setup>
|
||||
import ContextMenu from './ContextMenu.vue'
|
||||
import { useTabStore, useAppStore } from '@/store'
|
||||
import { useTabStore } from '@/store'
|
||||
|
||||
const router = useRouter()
|
||||
const appStore = useAppStore()
|
||||
const tabStore = useTabStore()
|
||||
|
||||
const contextMenuOption = reactive({
|
||||
@@ -85,12 +83,12 @@ async function handleContextMenu(e, tagItem) {
|
||||
border-radius: 4px !important;
|
||||
margin-right: 4px;
|
||||
&:hover {
|
||||
border: 1px solid var(--primary-color) !important;
|
||||
border: 1px solid rgb(var(--primary-color)) !important;
|
||||
}
|
||||
}
|
||||
.n-tabs-tab--active {
|
||||
border: 1px solid var(--primary-color) !important;
|
||||
background-color: var(--selected-bg) !important;
|
||||
border: 1px solid rgb(var(--primary-color)) !important;
|
||||
background-color: rgba(var(--primary-color), 0.1) !important;
|
||||
}
|
||||
.n-tabs-pad,
|
||||
.n-tabs-tab-pad,
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
class="i-me:gitee mr-16 cursor-pointer"
|
||||
@click="handleLinkClick('https://gitee.com/isme-admin/vue-naive-admin/tree/2.x')"
|
||||
/>
|
||||
|
||||
<ThemeSetting class="mr-16" />
|
||||
|
||||
<UserAvatar />
|
||||
</div>
|
||||
</AppCard>
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
class="i-me:gitee mr-16 cursor-pointer"
|
||||
@click="handleLinkClick('https://gitee.com/isme-admin/vue-naive-admin/tree/2.x')"
|
||||
/>
|
||||
|
||||
<ThemeSetting class="mr-16" />
|
||||
|
||||
<UserAvatar />
|
||||
</div>
|
||||
</AppCard>
|
||||
@@ -56,4 +59,8 @@ const { isFullscreen, toggle } = useFullscreen()
|
||||
function handleLinkClick(link) {
|
||||
window.open(link)
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
appStore.setThemeColor(appStore.primaryColor, appStore.isDark)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -8,32 +8,14 @@
|
||||
|
||||
export const defaultLayout = 'normal'
|
||||
|
||||
export const defaultPrimaryColor = '#316C72'
|
||||
|
||||
export const naiveThemeOverrides = {
|
||||
common: {
|
||||
primaryColor: '#316C72FF',
|
||||
primaryColorHover: '#316C72E3',
|
||||
primaryColorPressed: '#2B4C59FF',
|
||||
primaryColorSuppl: '#316C72E3',
|
||||
|
||||
infoColor: '#2080F0FF',
|
||||
infoColorHover: '#4098FCFF',
|
||||
infoColorPressed: '#1060C9FF',
|
||||
infoColorSuppl: '#4098FCFF',
|
||||
|
||||
successColor: '#18A058FF',
|
||||
successColorHover: '#36AD6AFF',
|
||||
successColorPressed: '#0C7A43FF',
|
||||
successColorSuppl: '#36AD6AFF',
|
||||
|
||||
warningColor: '#F0A020FF',
|
||||
warningColorHover: '#FCB040FF',
|
||||
warningColorPressed: '#C97C10FF',
|
||||
warningColorSuppl: '#FCB040FF',
|
||||
|
||||
errorColor: '#D03050FF',
|
||||
errorColorHover: '#DE576DFF',
|
||||
errorColorPressed: '#AB1F3FFF',
|
||||
errorColorSuppl: '#DE576DFF',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
|
||||
import { defineStore } from 'pinia'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { defaultLayout, naiveThemeOverrides } from '@/settings'
|
||||
import { generate, getRgbStr } from '@arco-design/color'
|
||||
import { defaultLayout, defaultPrimaryColor, naiveThemeOverrides } from '@/settings'
|
||||
|
||||
export const useAppStore = defineStore('app', {
|
||||
state: () => ({
|
||||
collapsed: false,
|
||||
isDark: useDark(),
|
||||
layout: defaultLayout,
|
||||
primaryColor: defaultPrimaryColor,
|
||||
naiveThemeOverrides,
|
||||
}),
|
||||
actions: {
|
||||
@@ -30,9 +32,25 @@ export const useAppStore = defineStore('app', {
|
||||
setLayout(v) {
|
||||
this.layout = v
|
||||
},
|
||||
setPrimaryColor(color) {
|
||||
this.primaryColor = color
|
||||
},
|
||||
setThemeColor(color = this.primaryColor, isDark = this.isDark) {
|
||||
const colors = generate(color, {
|
||||
list: true,
|
||||
dark: isDark,
|
||||
})
|
||||
document.body.style.setProperty('--primary-color', getRgbStr(colors[5]))
|
||||
this.naiveThemeOverrides.common = Object.assign(this.naiveThemeOverrides.common || {}, {
|
||||
primaryColor: colors[5],
|
||||
primaryColorHover: colors[4],
|
||||
primaryColorSuppl: colors[4],
|
||||
primaryColorPressed: colors[6],
|
||||
})
|
||||
},
|
||||
},
|
||||
persist: {
|
||||
paths: ['collapsed', 'naiveThemeOverrides'],
|
||||
paths: ['collapsed', 'layout', 'primaryColor', 'naiveThemeOverrides'],
|
||||
storage: sessionStorage,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -68,7 +68,7 @@ body {
|
||||
background: #bfbfbf;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--primary-color);
|
||||
background: rgb(var(--primary-color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user