Browse Source

feat: 暗黑模式

i18n
xiaoxian521 3 years ago
parent
commit
ebba7bc821
  1. 5
      package.json
  2. 45
      pnpm-lock.yaml
  3. 1
      src/assets/svg/dark.svg
  4. 1
      src/assets/svg/day.svg
  5. 2
      src/assets/svg/exit_screen.svg
  6. 2
      src/assets/svg/full_screen.svg
  7. 38
      src/layout/components/setting/index.vue
  8. 28
      src/style/dark.scss
  9. 1
      src/style/index.scss
  10. 6
      src/style/login.css
  11. 2
      src/views/login.vue

5
package.json

@ -36,7 +36,6 @@
"@vueuse/core": "^6.7.1",
"@vueuse/motion": "^2.0.0-beta.4",
"animate.css": "^4.1.1",
"await-to-js": "^3.0.0",
"axios": "^0.21.1",
"dayjs": "^1.10.7",
"element-plus": "1.2.0-beta.6",
@ -44,18 +43,15 @@
"font-awesome": "^4.7.0",
"js-cookie": "^3.0.1",
"lodash-es": "^4.17.21",
"lowdb": "^3.0.0",
"mitt": "^3.0.0",
"mockjs": "^1.1.0",
"nprogress": "^0.2.0",
"path": "^0.12.7",
"path-to-regexp": "^6.2.0",
"pinia": "^2.0.0-rc.14",
"qs": "^6.10.2",
"remixicon": "^2.5.0",
"resize-observer-polyfill": "^1.5.1",
"responsive-storage": "^1.0.11",
"typescript-cookie": "^1.0.0",
"vue": "^3.2.24",
"vue-i18n": "^9.2.0-beta.3",
"vue-router": "^4.0.12",
@ -80,7 +76,6 @@
"@zougt/vite-plugin-theme-preprocessor": "^1.4.0",
"autoprefixer": "10.2.4",
"babel-plugin-transform-remove-console": "6.9.4",
"chalk": "2.4.2",
"cross-env": "7.0.3",
"eslint": "7.30.0",
"eslint-plugin-prettier": "3.4.0",

45
pnpm-lock.yaml

@ -26,10 +26,8 @@ specifiers:
"@zougt/vite-plugin-theme-preprocessor": ^1.4.0
animate.css: ^4.1.1
autoprefixer: 10.2.4
await-to-js: ^3.0.0
axios: ^0.21.1
babel-plugin-transform-remove-console: 6.9.4
chalk: 2.4.2
cross-env: 7.0.3
dayjs: ^1.10.7
element-plus: 1.2.0-beta.6
@ -42,12 +40,10 @@ specifiers:
js-cookie: ^3.0.1
lint-staged: 11.1.2
lodash-es: ^4.17.21
lowdb: ^3.0.0
mitt: ^3.0.0
mockjs: ^1.1.0
nprogress: ^0.2.0
path: ^0.12.7
path-to-regexp: ^6.2.0
pinia: ^2.0.0-rc.14
postcss: 8.2.6
postcss-import: 14.0.0
@ -65,7 +61,6 @@ specifiers:
stylelint-config-standard: 22.0.0
stylelint-order: 4.1.0
typescript: 4.4.2
typescript-cookie: ^1.0.0
unplugin-element-plus: ^0.1.3
vite: 2.6.14
vite-plugin-mock: ^2.9.6
@ -86,7 +81,6 @@ dependencies:
"@vueuse/core": 6.7[email protected]
"@vueuse/motion": 2.0.0-[email protected]
animate.css: 4.1.1
await-to-js: 3.0.0
axios: 0.21.4
dayjs: 1.10.7
element-plus: 1.2.0-[email protected]
@ -94,18 +88,15 @@ dependencies:
font-awesome: 4.7.0
js-cookie: 3.0.1
lodash-es: 4.17.21
lowdb: 3.0.0
mitt: 3.0.0
mockjs: 1.1.0
nprogress: 0.2.0
path: 0.12.7
path-to-regexp: 6.2.0
pinia: 2.0[email protected][email protected]
qs: 6.10.2
remixicon: 2.5.0
resize-observer-polyfill: 1.5.1
responsive-storage: 1.0[email protected]
typescript-cookie: 1.0.0
vue: 3.2.24
vue-i18n: 9.2.0-[email protected]
vue-router: 4.0[email protected]
@ -130,7 +121,6 @@ devDependencies:
"@zougt/vite-plugin-theme-preprocessor": 1.4[email protected]
autoprefixer: 10.2[email protected]
babel-plugin-transform-remove-console: 6.9.4
chalk: 2.4.2
cross-env: 7.0.3
eslint: 7.30.0
eslint-plugin-prettier: 3.4[email protected][email protected]
@ -1855,14 +1845,6 @@ packages:
postcss-value-parser: 4.1.0
dev: true
/await-to-js/3.0.0:
resolution:
{
integrity: sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==
}
engines: { node: ">=6.0.0" }
dev: false
/axios/0.21.4:
resolution:
{
@ -4488,16 +4470,6 @@ packages:
}
dev: true
/lowdb/3.0.0:
resolution:
{
integrity: sha512-9KZRulmIcU8fZuWiaM0d5e2/nPnrFyXkeXVpqT+MJS+vgbgOf1EbtvgQmba8HwUFgDl1oeZR6XqEJnkJmQdKmg==
}
engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
dependencies:
steno: 2.1.0
dev: false
/lower-case/2.0.2:
resolution:
{
@ -5106,6 +5078,7 @@ packages:
{
integrity: sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==
}
dev: true
/path-type/4.0.0:
resolution:
@ -6361,14 +6334,6 @@ packages:
engines: { node: ">= 0.6" }
dev: true
/steno/2.1.0:
resolution:
{
integrity: sha512-mauOsiaqTNGFkWqIfwcm3y/fq+qKKaIWf1vf3ocOuTdco9XoHCO2AGF1gFYXuZFSWuP38Q8LBHBGJv2KnJSXyA==
}
engines: { node: ^14.13.1 || >=16.0.0 }
dev: false
/string-argv/0.3.1:
resolution:
{
@ -6830,14 +6795,6 @@ packages:
is-typedarray: 1.0.0
dev: true
/typescript-cookie/1.0.0:
resolution:
{
integrity: sha512-oYHAgQWDqheZXiq1ODzVwwl+8lGzK/ApsxAu1a4uyl+Yd9BuF0M5I3bowgb5oAlU3Qyqejcj5kDyOZe+y+W4SA==
}
engines: { node: ">=14" }
dev: false
/typescript/4.4.2:
resolution:
{

1
src/assets/svg/dark.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.38 2.019a7.5 7.5 0 1 0 10.6 10.6C21.662 17.854 17.316 22 12.001 22 6.477 22 2 17.523 2 12c0-5.315 4.146-9.661 9.38-9.981z"/></svg>

1
src/assets/svg/day.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></svg>

2
src/assets/svg/exit_screen.svg

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" class="re-screen" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><g fill="currentColor"><path d="M3.5 4H1V3h2V1h1v2.5l-.5.5zM13 3V1h-1v2.5l.5.5H15V3h-2zm-1 9.5V15h1v-2h2v-1h-2.5l-.5.5zM1 12v1h2v2h1v-2.5l-.5-.5H1zm11-1.5l-.5.5h-7l-.5-.5v-5l.5-.5h7l.5.5v5zM10 7H6v2h4V7z"></path></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" class="re-screen" color="#00000073" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><g fill="currentColor"><path d="M3.5 4H1V3h2V1h1v2.5l-.5.5zM13 3V1h-1v2.5l.5.5H15V3h-2zm-1 9.5V15h1v-2h2v-1h-2.5l-.5.5zM1 12v1h2v2h1v-2.5l-.5-.5H1zm11-1.5l-.5.5h-7l-.5-.5v-5l.5-.5h7l.5.5v5zM10 7H6v2h4V7z"></path></g></svg>

2
src/assets/svg/full_screen.svg

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" class="re-screen" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><g fill="currentColor"><path d="M3 12h10V4H3v8zm2-6h6v4H5V6zM2 6H1V2.5l.5-.5H5v1H2v3zm13-3.5V6h-1V3h-3V2h3.5l.5.5zM14 10h1v3.5l-.5.5H11v-1h3v-3zM2 13h3v1H1.5l-.5-.5V10h1v3z"></path></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" class="re-screen" color="#00000073" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><g fill="currentColor"><path d="M3 12h10V4H3v8zm2-6h6v4H5V6zM2 6H1V2.5l.5-.5H5v1H2v3zm13-3.5V6h-1V3h-3V2h3.5l.5.5zM14 10h1v3.5l-.5.5H11v-1h3v-3zM2 13h3v1H1.5l-.5-.5V10h1v3z"></path></g></svg>

38
src/layout/components/setting/index.vue

@ -14,7 +14,9 @@ import { getConfig } from "/@/config";
import { useRouter } from "vue-router";
import { emitter } from "/@/utils/mitt";
import { templateRef } from "@vueuse/core";
import dayIcon from "/@/assets/svg/day.svg";
import { debounce } from "/@/utils/debounce";
import darkIcon from "/@/assets/svg/dark.svg";
import { themeColorsType } from "../../types";
import { useAppStoreHook } from "/@/store/modules/app";
import { storageLocal, storageSession } from "/@/utils/storage";
@ -235,11 +237,33 @@ function setLayoutThemeColor(theme: string) {
});
instance.layout = { layout: useAppStoreHook().layout, theme };
}
let dataTheme = ref<boolean>(false);
//
function dataThemeChange() {
const body = document.documentElement as HTMLElement;
if (dataTheme.value) {
body.setAttribute("data-theme", "dark");
setLayoutThemeColor("light");
} else body.setAttribute("data-theme", "");
}
</script>
<template>
<panel>
<el-divider>主题风格</el-divider>
<el-divider>主题</el-divider>
<el-switch
v-model="dataTheme"
inline-prompt
class="pure-datatheme"
:active-icon="dayIcon"
:inactive-icon="darkIcon"
@change="dataThemeChange"
>
</el-switch>
<el-divider>导航栏模式</el-divider>
<ul class="pure-theme">
<el-tooltip class="item" content="左侧菜单模式" placement="bottom">
<li
@ -264,8 +288,8 @@ function setLayoutThemeColor(theme: string) {
</el-tooltip>
</ul>
<el-divider>主题色</el-divider>
<ul class="theme-color">
<el-divider v-if="!dataTheme">主题色</el-divider>
<ul class="theme-color" v-if="!dataTheme">
<li
v-for="(item, index) in themeColors"
:key="index"
@ -391,6 +415,14 @@ function setLayoutThemeColor(theme: string) {
font-weight: 700;
}
.pure-datatheme {
width: 100%;
height: 50px;
text-align: center;
display: block;
padding-top: 25px;
}
.pure-theme {
margin-top: 25px;
width: 100%;

28
src/style/dark.scss

@ -0,0 +1,28 @@
/* 暗黑模式 */
[data-theme="dark"] {
filter: invert(0.9) hue-rotate(180deg);
img,
.icon-svg,
.login-container {
filter: invert(1) hue-rotate(180deg);
}
// element plus
.el-radio-button__original-radio:checked + .el-radio-button__inner,
.el-image-viewer__close,
.el-image-viewer__actions__inner,
.el-image-viewer__next,
.el-image-viewer__prev {
color: #000 !important;
}
.el-overlay {
background-color: rgba(0, 0, 0, 0.05) !important;
}
.el-drawer {
box-shadow: 0 8px 10px -5px rgb(0 0 0 / 1%), 0 16px 24px 2px rgb(0 0 0 / 2%),
0 6px 30px 5px rgb(0 0 0 / 1%);
}
}

1
src/style/index.scss

@ -2,6 +2,7 @@
@import "./transition.scss";
@import "./element-plus.scss";
@import "./sidebar.scss";
@import "./dark.scss";
body {
width: 100%;

6
src/style/login.css

@ -6,7 +6,7 @@
z-index: -1;
}
.container {
.login-container {
width: 100vw;
height: 100vh;
display: grid;
@ -183,7 +183,7 @@ a:hover {
}
@media screen and (max-width: 1080px) {
.container {
.login-container {
grid-gap: 9rem;
}
}
@ -217,7 +217,7 @@ a:hover {
display: none;
}
.container {
.login-container {
grid-template-columns: 1fr;
}

2
src/views/login.vue

@ -71,7 +71,7 @@ function onPwdBlur() {
<template>
<img :src="bg" class="wave" />
<div class="container">
<div class="login-container">
<div class="img">
<component :is="currentWeek"></component>
</div>

Loading…
Cancel
Save