Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
有来技术
mall-admin
提交
a6882db1
M
mall-admin
项目概览
有来技术
/
mall-admin
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
mall-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a6882db1
编写于
3月 01, 2022
作者:
郝
郝先瑞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 系统设置添加主题动态切换
上级
108aeeb4
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
171 addition
and
57 deletion
+171
-57
src/App.vue
src/App.vue
+5
-1
src/components/RightPanel/index.vue
src/components/RightPanel/index.vue
+22
-19
src/components/ThemePicker/index.vue
src/components/ThemePicker/index.vue
+56
-0
src/layout/components/Settings/index.vue
src/layout/components/Settings/index.vue
+35
-32
src/layout/index.vue
src/layout/index.vue
+1
-1
src/store/modules/settings.ts
src/store/modules/settings.ts
+2
-1
src/styles/element-plus.scss
src/styles/element-plus.scss
+31
-1
src/styles/element-variables.module.scss
src/styles/element-variables.module.scss
+1
-1
src/utils/index.ts
src/utils/index.ts
+18
-1
未找到文件。
src/App.vue
浏览文件 @
a6882db1
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
,
watch
}
from
"
vue
"
;
import
{
computed
,
onMounted
,
ref
,
watch
}
from
"
vue
"
;
import
{
useAppStoreHook
}
from
"
@/store/modules/app
"
;
import
{
useAppStoreHook
}
from
"
@/store/modules/app
"
;
import
{
ElConfigProvider
}
from
'
element-plus
'
import
{
ElConfigProvider
}
from
'
element-plus
'
...
@@ -29,5 +29,9 @@ watch(language, (value) => {
...
@@ -29,5 +29,9 @@ watch(language, (value) => {
// 初始化立即执行,
// 初始化立即执行,
immediate
:
true
immediate
:
true
})
})
onMounted
(()
=>
{
const
style
=
localStorage
.
getItem
(
"
style
"
);
document
.
documentElement
.
style
.
cssText
=
style
as
string
;
})
</
script
>
</
script
>
src/components/RightPanel/index.vue
浏览文件 @
a6882db1
...
@@ -2,31 +2,28 @@
...
@@ -2,31 +2,28 @@
<div
ref=
"rightPanel"
:class=
"
{show:show}" class="rightPanel-container">
<div
ref=
"rightPanel"
:class=
"
{show:show}" class="rightPanel-container">
<div
class=
"rightPanel-background"
/>
<div
class=
"rightPanel-background"
/>
<div
class=
"rightPanel"
>
<div
class=
"rightPanel"
>
<div
class=
"handle-button"
:style=
"
{'top':buttonTop+'px','background-color':theme}" @click="show=!show">
<div
class=
"handle-button"
:style=
"
{'top':buttonTop+'px','background-color':theme}" @click="show=!show">
<Close
style=
"width: 1em; height: 1em;vertical-align: middle "
v-show=
"show"
/>
<Close
style=
"width: 1em; height: 1em;vertical-align: middle "
v-show=
"show"
/>
<Setting
style=
"width:1em; height:1em;vertical-align: middle "
v-show=
"!show"
/>
<Setting
style=
"width:1em; height:1em;vertical-align: middle "
v-show=
"!show"
/>
</div>
</div>
<div
class=
"rightPanel-items"
>
<div
class=
"rightPanel-items"
>
<slot/>
<slot/>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
onBeforeUnmount
,
onMounted
,
ref
,
watch
Effect
}
from
"
vue
"
;
import
{
computed
,
onBeforeUnmount
,
onMounted
,
ref
,
watch
}
from
"
vue
"
;
import
{
addClass
,
removeClass
}
from
'
@/utils/index
'
import
{
addClass
,
removeClass
}
from
'
@/utils/index
'
import
{
useSettingStoreHook
}
from
"
@/store/modules/settings
"
;
import
{
useSettingStoreHook
}
from
"
@/store/modules/settings
"
;
// 图标依赖
// 图标依赖
import
{
Close
,
Setting
}
from
'
@element-plus/icons-vue
'
import
{
Close
,
Setting
}
from
'
@element-plus/icons-vue
'
import
{
ElColorPicker
}
from
"
element-plus
"
;
const
props
=
defineProps
({
const
props
=
defineProps
({
clickNotClose
:
{
default
:
false
,
type
:
Boolean
},
buttonTop
:
{
buttonTop
:
{
default
:
250
,
default
:
250
,
type
:
Number
type
:
Number
...
@@ -37,11 +34,12 @@ const theme = computed(() => useSettingStoreHook().theme)
...
@@ -37,11 +34,12 @@ const theme = computed(() => useSettingStoreHook().theme)
const
show
=
ref
(
false
)
const
show
=
ref
(
false
)
watchEffect
(()
=>
{
watch
(
show
,
(
value
)
=>
{
if
(
show
.
value
&&
!
props
.
clickNotClose
)
{
console
.
log
(
'
show
'
,
value
)
if
(
value
)
{
addEventClick
()
addEventClick
()
}
}
if
(
show
.
value
)
{
if
(
value
)
{
addClass
(
document
.
body
,
'
showRightPanel
'
)
addClass
(
document
.
body
,
'
showRightPanel
'
)
}
else
{
}
else
{
removeClass
(
document
.
body
,
'
showRightPanel
'
)
removeClass
(
document
.
body
,
'
showRightPanel
'
)
...
@@ -53,24 +51,29 @@ function addEventClick() {
...
@@ -53,24 +51,29 @@ function addEventClick() {
}
}
function
closeSidebar
(
evt
:
any
)
{
function
closeSidebar
(
evt
:
any
)
{
const
parent
=
evt
.
target
.
closest
(
'
.rightPanel
'
)
// 主题选择点击不关闭
let
parent
=
evt
.
target
.
closest
(
'
.theme-picker-dropdown
'
)
if
(
parent
)
{
return
}
parent
=
evt
.
target
.
closest
(
'
.rightPanel
'
)
if
(
!
parent
)
{
if
(
!
parent
)
{
show
.
value
=
false
show
.
value
=
false
window
.
removeEventListener
(
'
click
'
,
closeSidebar
)
window
.
removeEventListener
(
'
click
'
,
closeSidebar
)
}
}
}
}
const
rightPanel
=
ref
(
null
)
const
rightPanel
=
ref
(
ElColorPicker
)
function
insertToBody
()
{
function
insertToBody
()
{
console
.
log
(
'
insertToBody
'
,
rightPanel
)
const
elx
=
rightPanel
.
value
as
any
const
elx
=
rightPanel
.
value
as
any
const
body
=
document
.
querySelector
(
'
body
'
)
as
any
const
body
=
document
.
querySelector
(
'
body
'
)
as
any
body
.
insertBefore
(
elx
,
body
.
firstChild
)
body
.
insertBefore
(
elx
,
body
.
firstChild
)
}
}
onMounted
(()
=>
{
onMounted
(()
=>
{
console
.
log
(
'
theme
'
,
useSettingStoreHook
().
theme
)
insertToBody
()
insertToBody
()
})
})
...
...
src/components/ThemePicker/index.vue
0 → 100644
浏览文件 @
a6882db1
<
template
>
<el-color-picker
v-model=
"theme"
:predefine=
"['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d' ]"
class=
"theme-picker"
popper-class=
"theme-picker-dropdown"
/>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
nextTick
,
watch
}
from
"
vue
"
;
import
{
useSettingStoreHook
}
from
"
@/store/modules/settings
"
;
import
{
useTagsViewStoreHook
}
from
"
@/store/modules/tagsView
"
;
import
{
useRoute
,
useRouter
}
from
"
vue-router
"
;
// 参考连接:https://juejin.cn/post/7024025899813044232#heading-1
import
{
mix
}
from
"
@/utils
"
;
// 白色混合色
const
mixWhite
=
"
#ffffff
"
;
// 黑色混合色
const
mixBlack
=
"
#000000
"
;
const
node
=
document
.
documentElement
;
const
theme
=
computed
(()
=>
useSettingStoreHook
().
theme
)
watch
(
theme
,
(
color
:
string
)
=>
{
node
.
style
.
setProperty
(
"
--el-color-primary
"
,
color
);
localStorage
.
setItem
(
"
theme
"
,
color
)
for
(
let
i
=
1
;
i
<
10
;
i
+=
1
)
{
node
.
style
.
setProperty
(
`--el-color-primary-light-
${
i
}
`
,
mix
(
color
,
mixWhite
,
i
*
0.1
));
}
node
.
style
.
setProperty
(
"
--el-color-primary-dark
"
,
mix
(
color
,
mixBlack
,
0.1
));
localStorage
.
setItem
(
"
style
"
,
node
.
style
.
cssText
);
})
</
script
>
<
style
>
.theme-message
,
.theme-picker-dropdown
{
z-index
:
99999
!important
;
}
.theme-picker
.el-color-picker__trigger
{
height
:
26px
!important
;
width
:
26px
!important
;
padding
:
2px
;
}
.theme-picker-dropdown
.el-color-dropdown__link-btn
{
display
:
none
;
}
</
style
>
src/layout/components/Settings/index.vue
浏览文件 @
a6882db1
<
template
>
<
template
>
<div
class=
"drawer-container"
>
<div
class=
"drawer-container"
>
<div>
<h3
class=
"drawer-title"
>
系统布局配置
</h3>
<h3
class=
"drawer-title"
>
系统布局配置
</h3>
<div
class=
"drawer-item"
>
<span>
主题颜色
</span>
<div
style=
"float: right;height: 26px;margin: -3px 8px 0 0;"
>
<theme-picker
@
change=
"themeChange"
/>
</div>
</div>
<div
class=
"drawer-item"
>
<div
class=
"drawer-item"
>
<span>
开启 Tags-View
</span>
<span>
开启 Tags-View
</span>
<el-switch
v-model=
"tagsView"
class=
"drawer-switch"
/>
<el-switch
v-model=
"
state.
tagsView"
class=
"drawer-switch"
/>
</div>
</div>
<div
class=
"drawer-item"
>
<div
class=
"drawer-item"
>
...
@@ -17,40 +22,38 @@
...
@@ -17,40 +22,38 @@
<span>
侧边栏 Logo
</span>
<span>
侧边栏 Logo
</span>
<el-switch
v-model=
"sidebarLogo"
class=
"drawer-switch"
/>
<el-switch
v-model=
"sidebarLogo"
class=
"drawer-switch"
/>
</div>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
setup
lang=
"ts"
>
import
{
defineComponent
,
reactive
,
toRefs
,
watch
}
from
"
vue
"
import
{
reactive
,
toRefs
,
watch
}
from
"
vue
"
;
import
{
useSettingStoreHook
}
from
"
@/store/modules/settings
"
;
import
{
useSettingStoreHook
}
from
"
@/store/modules/settings
"
;
export
default
defineComponent
({
import
ThemePicker
from
'
@/components/ThemePicker/index.vue
'
;
setup
()
{
const
state
=
reactive
({
const
state
=
reactive
({
fixedHeader
:
useSettingStoreHook
().
fixedHeader
,
fixedHeader
:
useSettingStoreHook
().
fixedHeader
,
tagsView
:
useSettingStoreHook
().
tagsView
,
tagsView
:
useSettingStoreHook
().
tagsView
,
sidebarLogo
:
useSettingStoreHook
().
sidebarLogo
,
sidebarLogo
:
useSettingStoreHook
().
sidebarLogo
themeChange
:
(
val
)
=>
{
})
useSettingStoreHook
().
changeSetting
(
{
key
:
'
theme
'
,
val
})
}
const
{
fixedHeader
,
tagsView
,
sidebarLogo
}
=
toRefs
(
state
)
})
watch
(()
=>
state
.
fixedHeader
,(
value
)
=>
{
function
themeChange
(
val
:
any
)
{
useSettingStoreHook
().
changeSetting
(
{
key
:
'
fixedHeader
'
,
value
})
useSettingStoreHook
().
changeSetting
({
key
:
'
theme
'
,
value
:
val
})
})
}
watch
(()
=>
state
.
tagsView
,
(
value
)
=>
{
watch
(()
=>
state
.
fixedHeader
,
(
value
)
=>
{
useSettingStoreHook
().
changeSetting
(
{
key
:
'
showTagsView
'
,
value
})
useSettingStoreHook
().
changeSetting
({
key
:
'
fixedHeader
'
,
value
:
value
})
})
})
watch
(()
=>
state
.
sidebarLogo
,
(
value
)
=>
{
watch
(()
=>
state
.
tagsView
,
(
value
)
=>
{
useSettingStoreHook
().
changeSetting
(
{
key
:
'
sidebarLogo
'
,
value
})
useSettingStoreHook
().
changeSetting
({
key
:
'
showTagsView
'
,
value
:
value
})
})
return
{
...
toRefs
(
state
)
}
}
})
})
watch
(()
=>
state
.
sidebarLogo
,
(
value
)
=>
{
useSettingStoreHook
().
changeSetting
({
key
:
'
sidebarLogo
'
,
value
:
value
})
})
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
...
...
src/layout/index.vue
浏览文件 @
a6882db1
<
template
>
<
template
>
<div
:class=
"classObj"
class=
"app-wrapper"
>
<div
:class=
"classObj"
class=
"app-wrapper"
>
<div
v-if=
"device==='mobile'
&&
sidebar.opened"
class=
"drawer-bg"
@
click=
"handleClickOutside"
/>
<div
v-if=
"device==='mobile'
&&
sidebar.opened"
class=
"drawer-bg"
@
click=
"handleClickOutside"
/>
<sidebar
class=
"sidebar-container"
/>
<sidebar
class=
"sidebar-container"
/>
<div
:class=
"
{hasTagsView:needTagsView}" class="main-container">
<div
:class=
"
{hasTagsView:needTagsView}" class="main-container">
<div
:class=
"
{'fixed-header':fixedHeader}">
<div
:class=
"
{'fixed-header':fixedHeader}">
...
...
src/store/modules/settings.ts
浏览文件 @
a6882db1
...
@@ -2,13 +2,14 @@ import {defineStore} from "pinia";
...
@@ -2,13 +2,14 @@ import {defineStore} from "pinia";
import
{
store
}
from
"
@/store
"
;
import
{
store
}
from
"
@/store
"
;
import
{
SettingState
}
from
"
@/store/interface
"
;
import
{
SettingState
}
from
"
@/store/interface
"
;
import
defaultSettings
from
'
../../settings
'
import
defaultSettings
from
'
../../settings
'
const
{
showSettings
,
tagsView
,
fixedHeader
,
sidebarLogo
}
=
defaultSettings
const
{
showSettings
,
tagsView
,
fixedHeader
,
sidebarLogo
}
=
defaultSettings
import
variables
from
'
@/styles/element-variables.module.scss
'
import
variables
from
'
@/styles/element-variables.module.scss
'
export
const
useSettingStore
=
defineStore
({
export
const
useSettingStore
=
defineStore
({
id
:
"
setting
"
,
id
:
"
setting
"
,
state
:
():
SettingState
=>
({
state
:
():
SettingState
=>
({
theme
:
variables
.
theme
,
theme
:
localStorage
.
get
(
"
theme
"
)
||
variables
.
theme
,
showSettings
:
showSettings
,
showSettings
:
showSettings
,
tagsView
:
tagsView
,
tagsView
:
tagsView
,
fixedHeader
:
fixedHeader
,
fixedHeader
:
fixedHeader
,
...
...
src/styles/element-plus.scss
浏览文件 @
a6882db1
:root
{
:root
{
--el-color-primary
:
#409EFF
;
// 这里可以设置你自定义的颜色变量
// 这个是element主要按钮:active的颜色,当主题更改后此变量的值也随之更改
--el-color-primary-dark
:
#0d84ff
;
}
/* 核心组件的变量,下面这些样式是必须要写的 */
.el-link.el-link--primary
:hover
{
color
:
var
(
--
el-color-primary-light-2
)
!
important
;
}
.el-tag
{
--el-tag-bg-color
:
var
(
--
el-color-primary-light-9
);
--el-tag-border-color
:
var
(
--
el-color-primary-light-8
);
--el-tag-text-color
:
var
(
--
el-color-primary
);
--el-tag-hover-color
:
var
(
--
el-color-primary
);
}
.el-button--default
:active
{
color
:
var
(
--
el-color-primary-dark
)
!
important
;
border-color
:
var
(
--
el-color-primary-dark
)
!
important
;
}
.el-button--primary
{
--el-button-text-color
:
var
(
--
el-color-white
)
!
important
;
--el-button-bg-color
:
var
(
--
el-color-primary
)
!
important
;
--el-button-border-color
:
var
(
--
el-color-primary
)
!
important
;
--el-button-hover-bg-color
:
var
(
--
el-color-primary-light-2
)
!
important
;
--el-button-hover-border-color
:
var
(
--
el-color-primary-light-2
)
!
important
;
--el-button-active-bg-color
:
var
(
--
el-color-primary-dark
)
!
important
;
--el-button-active-border-color
:
var
(
--
el-color-primary-dark
)
!
important
;
}
}
// 覆盖 element-plus 的样式
// 覆盖 element-plus 的样式
...
...
src/styles/element-variables.module.scss
浏览文件 @
a6882db1
/**
/**
* I think element
-ui's
default theme color is too light for long-term use.
* I think element default theme color is too light for long-term use.
* So I modified the default color and you can modify it to your liking.
* So I modified the default color and you can modify it to your liking.
* https://vitejs.cn/guide/features.html#postcss
* https://vitejs.cn/guide/features.html#postcss
**/
**/
...
...
src/utils/index.ts
浏览文件 @
a6882db1
...
@@ -27,4 +27,21 @@ export function removeClass(ele: HTMLElement, cls: string) {
...
@@ -27,4 +27,21 @@ export function removeClass(ele: HTMLElement, cls: string) {
const
reg
=
new
RegExp
(
'
(
\\
s|^)
'
+
cls
+
'
(
\\
s|$)
'
)
const
reg
=
new
RegExp
(
'
(
\\
s|^)
'
+
cls
+
'
(
\\
s|$)
'
)
ele
.
className
=
ele
.
className
.
replace
(
reg
,
'
'
)
ele
.
className
=
ele
.
className
.
replace
(
reg
,
'
'
)
}
}
}
}
\ No newline at end of file
export
function
mix
(
color1
:
string
,
color2
:
string
,
weight
:
number
)
{
weight
=
Math
.
max
(
Math
.
min
(
Number
(
weight
),
1
),
0
);
let
r1
=
parseInt
(
color1
.
substring
(
1
,
3
),
16
);
let
g1
=
parseInt
(
color1
.
substring
(
3
,
5
),
16
);
let
b1
=
parseInt
(
color1
.
substring
(
5
,
7
),
16
);
let
r2
=
parseInt
(
color2
.
substring
(
1
,
3
),
16
);
let
g2
=
parseInt
(
color2
.
substring
(
3
,
5
),
16
);
let
b2
=
parseInt
(
color2
.
substring
(
5
,
7
),
16
);
let
r
=
Math
.
round
(
r1
*
(
1
-
weight
)
+
r2
*
weight
);
let
g
=
Math
.
round
(
g1
*
(
1
-
weight
)
+
g2
*
weight
);
let
b
=
Math
.
round
(
b1
*
(
1
-
weight
)
+
b2
*
weight
);
const
rStr
=
(
"
0
"
+
(
r
||
0
).
toString
(
16
)).
slice
(
-
2
);
const
gStr
=
(
"
0
"
+
(
g
||
0
).
toString
(
16
)).
slice
(
-
2
);
const
bStr
=
(
"
0
"
+
(
b
||
0
).
toString
(
16
)).
slice
(
-
2
);
return
"
#
"
+
rStr
+
gStr
+
bStr
;
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录