Demo:支持夜间模式

This commit is contained in:
wanglin2
2023-07-24 10:12:53 +08:00
parent 4ee458c509
commit d5e4044fb2
17 changed files with 348 additions and 31 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="container">
<div class="container" :class="{ isDark: isDark }">
<template v-if="show">
<Toolbar v-if="!isZenMode"></Toolbar>
<Edit></Edit>
@@ -26,9 +26,15 @@ export default {
},
computed: {
...mapState({
isZenMode: state => state.localConfig.isZenMode
isZenMode: state => state.localConfig.isZenMode,
isDark: state => state.isDark
})
},
watch: {
isDark() {
this.setBodyDark()
}
},
async created() {
this.initLocalConfig()
const loading = this.$loading({
@@ -38,6 +44,7 @@ export default {
await this.getUserMindMapData()
this.show = true
loading.close()
this.setBodyDark()
},
methods: {
...mapActions(['getUserMindMapData']),
@@ -56,12 +63,110 @@ export default {
...config
})
}
},
setBodyDark() {
this.isDark
? document.body.classList.add('isDark')
: document.body.classList.remove('isDark')
}
}
}
</script>
<style lang="less" scoped>
.container {
<style lang="less">
.container {}
body {
&.isDark {
.el-input__inner {
background-color: #363b3f;
border-color: hsla(0, 0%, 100%, 0.1);
color: hsla(0, 0%, 100%, 0.9);
}
.el-input.is-disabled .el-input__inner {
background-color: #363b3f;
border-color: hsla(0, 0%, 100%, 0.1);
color: hsla(0,0%,100%,.3);
}
/* el-select */
.el-select-dropdown {
background-color: #36393d;
border-color: hsla(0, 0%, 100%, 0.1);
.el-select-dropdown__item {
color: hsla(0, 0%, 100%, 0.6);
}
.el-select-dropdown__item.selected {
color: #409eff;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
background-color: hsla(0, 0%, 100%, 0.05);
}
}
.el-select .el-input.is-disabled .el-input__inner:hover {
border-color: hsla(0, 0%, 100%, 0.1);
}
/* el-popper*/
.el-popper {
background-color: #36393d;
border-color: hsla(0, 0%, 100%, 0.1);
}
.el-popper[x-placement^='bottom'] .popper__arrow {
background-color: #36393d;
}
.el-popper[x-placement^='bottom'] .popper__arrow::after {
border-bottom-color: #36393d;
}
.el-popper[x-placement^=top] .popper__arrow {
background-color: #36393d;
}
.el-popper[x-placement^=top] .popper__arrow::after {
border-top-color: #36393d;
}
/* el-tabs */
.el-tabs__item {
color: hsla(0, 0%, 100%, 0.6);
&:hover,
&.is-active {
color: #409EFF;
}
}
.el-tabs__nav-wrap::after {
background-color: hsla(0, 0%, 100%, 0.6);
}
/* el-slider */
.el-slider__runway {
background-color: hsla(0, 0%, 100%, 0.6);
}
/* el-radio-group */
.el-radio-group {
.el-radio-button__inner {
background-color: #36393d;
color: hsla(0, 0%, 100%, 0.6);
}
.el-radio-button__orig-radio:checked+.el-radio-button__inner {
color: #FFF;
background-color: #409EFF;
}
}
}
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<Sidebar ref="sidebar" :title="$t('baseStyle.title')">
<div class="sidebarContent" v-if="data">
<div class="sidebarContent" :class="{ isDark: isDark }" v-if="data">
<!-- 背景 -->
<div class="title noTop">{{ $t('baseStyle.background') }}</div>
<div class="row">
@@ -711,7 +711,7 @@ export default {
}
},
computed: {
...mapState(['activeSidebar', 'localConfig']),
...mapState(['activeSidebar', 'localConfig', 'isDark']),
lineStyleList() {
return lineStyleList[this.$i18n.locale] || lineStyleList.zh
@@ -922,6 +922,20 @@ export default {
padding: 20px;
padding-top: 10px;
&.isDark {
.title {
color: #fff;
}
.row {
.rowItem {
.name {
color: hsla(0,0%,100%,.6);
}
}
}
}
.title {
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;

View File

@@ -1,5 +1,5 @@
<template>
<div>
<div class="colorContainer" :class="{ isDark: isDark }">
<div class="colorList">
<span
class="colorItem"
@@ -22,6 +22,7 @@
<script>
import { colorList } from '@/config'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -42,6 +43,9 @@ export default {
selectColor: ''
}
},
computed: {
...mapState(['isDark']),
},
watch: {
color() {
this.selectColor = this.color
@@ -73,6 +77,14 @@ export default {
</script>
<style lang="less" scoped>
.colorContainer {
&.isDark {
.moreColor {
color: hsla(0, 0%, 100%, 0.6);
}
}
}
.colorList {
width: 240px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="countContainer">
<div class="countContainer" :class="{ isDark: isDark }">
<div class="item">
<span class="name">{{ $t('count.words') }}</span>
<span class="value">{{ words }}</span>
@@ -12,6 +12,8 @@
</template>
<script>
import { mapState } from 'vuex'
/**
* @Author: 王林
* @Date: 2021-06-24 22:53:10
@@ -29,6 +31,9 @@ export default {
num: 0
}
},
computed: {
...mapState(['isDark']),
},
created() {
this.$bus.$on('data_change', this.onDataChange)
},
@@ -82,6 +87,14 @@ export default {
font-size: 12px;
display: flex;
&.isDark {
background: #262a2e;
.item {
color: hsla(0,0%,100%,.6);
}
}
.item {
color: #555;
margin-right: 15px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="fullscreenContainer">
<div class="fullscreenContainer" :class="{ isDark: isDark }">
<el-tooltip
class="item"
effect="dark"
@@ -32,6 +32,9 @@ export default {
props: {
mindMap: {
type: Object
},
isDark: {
type: Boolean
}
},
data() {
@@ -63,6 +66,12 @@ export default {
display: flex;
align-items: center;
&.isDark {
.btn {
color: hsla(0,0%,100%,.6);
}
}
.item {
margin-right: 12px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="mouseActionContainer">
<div class="mouseActionContainer" :class="{ isDark: isDark }">
<el-tooltip
class="item"
effect="dark"
@@ -32,6 +32,9 @@ export default {
props: {
mindMap: {
type: Object
},
isDark: {
type: Boolean
}
},
data() {
@@ -64,6 +67,12 @@ export default {
display: flex;
align-items: center;
&.isDark{
.btn {
color: hsla(0,0%,100%,.6);
}
}
.item {
margin-right: 12px;

View File

@@ -1,5 +1,5 @@
<template>
<div class="navigatorContainer">
<div class="navigatorContainer" :class="{ isDark: isDark }">
<div class="item">
<el-select
v-model="lang"
@@ -16,7 +16,7 @@
</el-select>
</div>
<div class="item">
<MouseAction :mindMap="mindMap"></MouseAction>
<MouseAction :isDark="isDark" :mindMap="mindMap"></MouseAction>
</div>
<div class="item">
<el-tooltip
@@ -59,10 +59,10 @@
</el-tooltip>
</div>
<div class="item">
<Fullscreen :mindMap="mindMap"></Fullscreen>
<Fullscreen :isDark="isDark" :mindMap="mindMap"></Fullscreen>
</div>
<div class="item">
<Scale :mindMap="mindMap"></Scale>
<Scale :isDark="isDark" :mindMap="mindMap"></Scale>
</div>
<div class="item">
<a href="https://github.com/wanglin2/mind-map" target="_blank">
@@ -79,6 +79,7 @@ import MouseAction from './MouseAction.vue'
import { langList } from '@/config'
import i18n from '@/i18n'
import { storeLang, getLang } from '@/api'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -105,6 +106,9 @@ export default {
openMiniMap: false
}
},
computed: {
...mapState(['isDark']),
},
methods: {
readonlyChange() {
this.isReadonly = !this.isReadonly
@@ -138,6 +142,20 @@ export default {
display: flex;
align-items: center;
&.isDark {
background: #262a2e;
.item {
a {
color: hsla(0,0%,100%,.6);
}
.btn {
color: hsla(0,0%,100%,.6);
}
}
}
.item {
margin-right: 20px;

View File

@@ -2,6 +2,7 @@
<Sidebar ref="sidebar" :title="$t('outline.title')">
<el-tree
class="outlineTree"
:class="{ isDark: isDark }"
:data="data"
:props="defaultProps"
:expand-on-click-node="false"
@@ -53,7 +54,7 @@ export default {
}
},
computed: {
...mapState(['activeSidebar'])
...mapState(['activeSidebar', 'isDark'])
},
watch: {
activeSidebar(val) {
@@ -150,6 +151,10 @@ export default {
}
.outlineTree {
&.isDark {
background-color: #262a2e;
}
/deep/ .el-tree-node__content {
height: auto;
margin: 5px 0;

View File

@@ -1,5 +1,5 @@
<template>
<div class="scaleContainer">
<div class="scaleContainer" :class="{ isDark: isDark }">
<el-tooltip
class="item"
effect="dark"
@@ -31,6 +31,9 @@ export default {
props: {
mindMap: {
type: Object
},
isDark: {
type: Boolean
}
},
data() {
@@ -84,6 +87,16 @@ export default {
display: flex;
align-items: center;
&.isDark {
.btn {
color: hsla(0,0%,100%,.6);
}
.scaleInfo {
color: hsla(0,0%,100%,.6);
}
}
.btn {
cursor: pointer;
}

View File

@@ -1,6 +1,6 @@
<template>
<Sidebar ref="sidebar" :title="$t('shortcutKey.title')">
<div class="box">
<div class="box" :class="{ isDark: isDark }">
<div v-for="item in shortcutKeyList" :key="item.type">
<div class="title">{{ item.type }}</div>
<div class="list" v-for="item2 in item.list" :key="item2.value">
@@ -38,7 +38,7 @@ export default {
return {}
},
computed: {
...mapState(['activeSidebar']),
...mapState(['activeSidebar', 'isDark']),
shortcutKeyList() {
return shortcutKeyList[this.$i18n.locale] || shortcutKeyList.zh
@@ -60,6 +60,28 @@ export default {
.box {
padding: 0 20px;
&.isDark {
.title {
color: #fff;
}
.list {
.item {
.icon {
color: hsla(0,0%,100%,.6);
}
.name {
color: hsla(0,0%,100%,.6);
}
.value {
color: hsla(0,0%,100%,.3);
}
}
}
}
.title {
font-size: 16px;
font-weight: 500;

View File

@@ -2,7 +2,7 @@
<div
class="sidebarContainer"
@click.stop
:class="{ show: show }"
:class="{ show: show, isDark: isDark }"
:style="{ zIndex: zIndex }"
>
<span class="closeBtn el-icon-close" @click="close"></span>
@@ -38,6 +38,9 @@ export default {
zIndex: 0
}
},
computed: {
...mapState(['isDark']),
},
watch: {
show(val, oldVal) {
if (val && !oldVal) {
@@ -69,6 +72,20 @@ export default {
flex-direction: column;
transition: all 0.3s;
&.isDark {
background-color: #262a2e;
border-left-color: hsla(0,0%,100%,.1);
.sidebarHeader {
border-bottom-color: hsla(0,0%,100%,.1);
color: #fff;
}
.closeBtn {
color: #fff;
}
}
&.show {
right: 0;
}

View File

@@ -2,7 +2,7 @@
<div
class="sidebarTriggerContainer"
@click.stop
:class="{ hasActive: show && activeSidebar, show: show }"
:class="{ hasActive: show && activeSidebar, show: show, isDark: isDark }"
>
<div class="toggleShowBtn" :class="{hide: !show}" @click="show = !show">
<span class="iconfont iconjiantouyou"></span>
@@ -39,7 +39,7 @@ export default {
}
},
computed: {
...mapState(['activeSidebar']),
...mapState(['activeSidebar', 'isDark']),
triggerList() {
return sidebarTriggerList[this.$i18n.locale] || sidebarTriggerList.zh
@@ -64,6 +64,20 @@ export default {
top: 50%;
transform: translateY(-50%);
&.isDark {
.trigger {
background-color: #262a2e;
.triggerItem {
color: hsla(0,0%,100%,.6);
&:hover {
background-color: hsla(0,0%,100%,.05);
}
}
}
}
&.show {
right: 0;
}

View File

@@ -1,6 +1,6 @@
<template>
<Sidebar ref="sidebar" :title="$t('strusture.title')">
<div class="layoutList">
<div class="layoutList" :class="{ isDark: isDark }">
<div
class="layoutItem"
v-for="item in layoutList"
@@ -47,7 +47,7 @@ export default {
}
},
computed: {
...mapState(['activeSidebar'])
...mapState(['activeSidebar', 'isDark'])
},
watch: {
activeSidebar(val) {
@@ -80,6 +80,12 @@ export default {
.layoutList {
padding: 20px;
&.isDark {
.name {
color: #fff;
}
}
.layoutItem {
width: 100%;
cursor: pointer;

View File

@@ -1,6 +1,6 @@
<template>
<Sidebar ref="sidebar" :title="$t('style.title')">
<div class="styleBox" v-if="activeNodes.length > 0">
<div class="styleBox" :class="{ isDark: isDark }" v-if="activeNodes.length > 0">
<el-tabs class="tab" v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane :label="$t('style.normal')" name="normal"></el-tab-pane>
<el-tab-pane :label="$t('style.active')" name="active"></el-tab-pane>
@@ -435,7 +435,7 @@ export default {
}
},
computed: {
...mapState(['activeSidebar']),
...mapState(['activeSidebar', 'isDark']),
fontFamilyList() {
return fontFamilyList[this.$i18n.locale] || fontFamilyList.zh
@@ -623,6 +623,28 @@ export default {
display: flex;
flex-direction: column;
&.isDark {
.sidebarContent {
.title {
color: #fff;
}
.row {
.rowItem {
.name {
color: hsla(0,0%,100%,.6);
}
}
.styleBtn {
background-color: #363b3f;
color: hsla(0, 0%, 100%, 0.6);
border-color: hsla(0, 0%, 100%, 0.1);
}
}
}
}
.tab {
flex-grow: 0;
flex-shrink: 0;

View File

@@ -1,6 +1,6 @@
<template>
<Sidebar ref="sidebar" :title="$t('theme.title')">
<div class="themeList">
<div class="themeList" :class="{ isDark: isDark }">
<div
class="themeItem"
v-for="item in themeList"
@@ -48,7 +48,7 @@ export default {
}
},
computed: {
...mapState(['activeSidebar'])
...mapState(['activeSidebar', 'isDark'])
},
watch: {
activeSidebar(val) {
@@ -84,6 +84,12 @@ export default {
.themeList {
padding: 20px;
&.isDark {
.name {
color: #fff;
}
}
.themeItem {
width: 100%;
cursor: pointer;

View File

@@ -1,5 +1,5 @@
<template>
<div class="toolbarContainer">
<div class="toolbarContainer" :class="{ isDark: isDark }">
<div class="toolbar">
<!-- 节点操作 -->
<div class="toolbarBlock">
@@ -199,7 +199,7 @@ export default {
}
},
computed: {
...mapState(['isHandleLocalFile']),
...mapState(['isHandleLocalFile', 'isDark']),
hasRoot() {
return (
this.activeNodes.findIndex(node => {
@@ -447,6 +447,33 @@ export default {
<style lang="less" scoped>
.toolbarContainer {
&.isDark {
.toolbar {
color: hsla(0,0%,100%,.9);
.toolbarBlock {
background-color: #262a2e;
}
.toolbarBtn {
.icon {
background: transparent;
border-color: transparent;
}
&:hover {
&:not(.disabled) {
.icon {
background: hsla(0,0%,100%,.05);
}
}
}
&.disabled {
color: #54595f;
}
}
}
}
.toolbar {
position: fixed;
left: 50%;
@@ -522,7 +549,6 @@ export default {
}
@media screen and (max-width: 1040px) {
.toolbarContainer {
.toolbar {
left: 20px;

View File

@@ -17,7 +17,8 @@ const store = new Vuex.Store({
// 鼠标行为
useLeftKeySelectionRightKeyDrag: false
},
activeSidebar: '' // 当前显示的侧边栏
activeSidebar: '', // 当前显示的侧边栏
isDark: false,// 是否是暗黑模式
},
mutations: {
/**
@@ -61,6 +62,11 @@ const store = new Vuex.Store({
*/
setActiveSidebar(state, data) {
state.activeSidebar = data
},
// 设置暗黑模式
setIsDark(state, data) {
state.isDark = data
}
},
actions: {