feat: 系统设置添加主题动态切换

This commit is contained in:
郝先瑞
2022-03-01 23:45:07 +08:00
parent 108aeeb43a
commit a6882db1dd
9 changed files with 170 additions and 56 deletions

View File

@@ -2,31 +2,28 @@
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
<div class="rightPanel-background"/>
<div class="rightPanel">
<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"/>
<Setting style="width:1em; height:1em;vertical-align: middle " v-show="!show"/>
</div>
<div class="rightPanel-items">
<slot/>
</div>
<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"/>
<Setting style="width:1em; height:1em;vertical-align: middle " v-show="!show"/>
</div>
<div class="rightPanel-items">
<slot/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {computed, onBeforeUnmount, onMounted, ref, watchEffect} from "vue";
import {computed, onBeforeUnmount, onMounted, ref, watch} from "vue";
import {addClass, removeClass} from '@/utils/index'
import {useSettingStoreHook} from "@/store/modules/settings";
// 图标依赖
import {Close, Setting} from '@element-plus/icons-vue'
import {ElColorPicker} from "element-plus";
const props = defineProps({
clickNotClose: {
default: false,
type: Boolean
},
buttonTop: {
default: 250,
type: Number
@@ -37,11 +34,12 @@ const theme = computed(() => useSettingStoreHook().theme)
const show = ref(false)
watchEffect(() => {
if (show.value && !props.clickNotClose) {
watch(show, (value) => {
console.log('show', value)
if (value) {
addEventClick()
}
if (show.value) {
if (value) {
addClass(document.body, 'showRightPanel')
} else {
removeClass(document.body, 'showRightPanel')
@@ -53,24 +51,29 @@ function addEventClick() {
}
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) {
show.value = false
window.removeEventListener('click', closeSidebar)
}
}
const rightPanel = ref(null)
const rightPanel = ref(ElColorPicker)
function insertToBody() {
console.log('insertToBody', rightPanel)
const elx = rightPanel.value as any
const body = document.querySelector('body') as any
body.insertBefore(elx, body.firstChild)
}
onMounted(() => {
console.log('theme', useSettingStoreHook().theme)
insertToBody()
})

View File

@@ -0,0 +1,56 @@
<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>