177 lines
4.6 KiB
Markdown
177 lines
4.6 KiB
Markdown
---
|
||
sidebar: auto
|
||
---
|
||
# 主题设置
|
||
|
||
## 目录结构
|
||
#### `src/theme` 下,后期继续补充,样式都会写在这个文件夹下:
|
||
|
||
```ts
|
||
├── theme
|
||
├── common
|
||
│ ├── transition.scss (页面过渡动画)
|
||
│ └── var.scss (全局主题样式,用于全局改变样式)
|
||
│
|
||
├── mixins
|
||
│ ├── element-mixins.scss (定义重置的element plus混入复用样式)
|
||
│ ├── function.scs (全局主题颜色调用混入函数)
|
||
│ └── mixins.scss (定义一些常用的全局混入样式)
|
||
│
|
||
├── app.scss (页面主样式,用于重置浏览器默认样式)
|
||
├── base.scss (基础样式、过渡动画等)
|
||
├── element.scss (重置的element plus样式,用于改变主题)
|
||
├── index.scss (页面样式出口)
|
||
└── media.scss (手机适配样式)
|
||
```
|
||
|
||
|
||
## scss 部分函数说明
|
||
#### 1、scss @mixin
|
||
[scss官方中文文档](https://www.sass.hk/docs/),具体请查阅官方文档。使用方法:
|
||
|
||
- 1.1 定义
|
||
|
||
```scss
|
||
/* Button 按钮
|
||
------------------------------- */
|
||
@mixin Button($main, $c1, $c2) {
|
||
color: set-color($main);
|
||
background: set-color($c1);
|
||
border-color: set-color($c2);
|
||
}
|
||
```
|
||
|
||
- 1.2 页面中使用,先引入,然后在 `css` 类中通过 `@include` 使用
|
||
|
||
```scss
|
||
@import 'mixins/element-mixins.scss';
|
||
|
||
// default
|
||
.el-button--default:hover,
|
||
.el-button--default:focus {
|
||
@include Button(primary, primary-light-8, primary-light-6);
|
||
}
|
||
```
|
||
|
||
#### 2、scss @function
|
||
|
||
- 2.1 定义函数
|
||
|
||
```scss
|
||
/* 颜色调用函数
|
||
------------------------------- */
|
||
@function set-color($key) {
|
||
@return var(--color-#{$key});
|
||
}
|
||
```
|
||
|
||
- 2.2 不理解?请看这个 `css3 :root` [CSS var() 函数](https://www.runoob.com/cssref/func-var.html)
|
||
|
||
```scss
|
||
/* 定义一个名为 "--main-bg-color" 的属性,然后使用 var() 函数调用该属性: */
|
||
:root {
|
||
--main-bg-color: red;
|
||
}
|
||
|
||
#div1 {
|
||
background-color: var(--main-bg-color);
|
||
}
|
||
|
||
#div2 {
|
||
background-color: var(--main-bg-color);
|
||
}
|
||
```
|
||
|
||
#### 3、为什么不使用这种写法放进 :root 中?
|
||
|
||
```scss
|
||
$colors: (
|
||
primary: #409eff,
|
||
success: #67c23a,
|
||
info: #909399,
|
||
warning: #e6a23c,
|
||
danger: #f56c6c
|
||
)
|
||
|
||
:root {
|
||
@each $key, $value in $colors {
|
||
--color-#{$key}: #{$value};
|
||
}
|
||
}
|
||
```
|
||
|
||
- 因为 scss 不支持这种嵌套 `mix(var(--color-primary), var(--color-success), 10%)`,lighten / darken / saturate / desaturate 等,从而无法用
|
||
- 从而无法用 `document.documentElement.style.setProperty('--color-primary', 'blue');` 改变样式
|
||
|
||
|
||
## 具体实现自定义全局主题
|
||
|
||
实现方法,以下方法不晓得会不会影响页面渲染性能:
|
||
|
||
- 1、定义全局 :root 初始变量,路径:`src/theme/common/var.scss`
|
||
- 2、编写覆盖 element plus 的样式:路径:`src/theme/element.scss`
|
||
- 3、页面通过 `document.documentElement.style.setProperty` 方法改变 `:root` 中的值
|
||
|
||
::: tip 提示
|
||
第一第二步就不介绍了,直接去路径去看就懂了。接下来我们讲讲第三步:
|
||
:::
|
||
|
||
#### 1、通过 `document.documentElement.style.setProperty` 改变颜色值 [setProperty 文档](https://developer.mozilla.org/zh-CN/docs/Web/API/CSSStyleDeclaration/setProperty)
|
||
|
||
```ts
|
||
// setup 中
|
||
import { reactive, toRefs } from "vue"
|
||
|
||
export defalut {
|
||
setup() {
|
||
const state = reactive({
|
||
color: ''
|
||
})
|
||
function colorChange() {
|
||
// 设置颜色
|
||
document.documentElement.style.setProperty(
|
||
"--color-primary",
|
||
state.color
|
||
)
|
||
// 设置颜色变浅
|
||
document.documentElement.style.setProperty(
|
||
"--color-primary-light-1",
|
||
getLightColor(state.color1, 0.1)
|
||
)
|
||
}
|
||
return {
|
||
colorChange,
|
||
...toRefs(state)
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 2、getLightColor 颜色变浅方法
|
||
|
||
路径在:`src/utils/theme.ts`
|
||
|
||
```ts
|
||
// 变浅颜色值,level为加深的程度,限0-1之间
|
||
export function getLightColor(color: any, level: number) {
|
||
let reg = /^\#?[0-9A-F]{6}$/;
|
||
if (!reg.test(color)) return ElMessage({type:'warning',message:"输入错误的hex颜色值"});
|
||
let rgb = hexToRgb(color);
|
||
for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]);
|
||
return rgbToHex(rgb[0], rgb[1], rgb[2]);
|
||
}
|
||
```
|
||
|
||
#### 3、到此就完成了主题的全局变色了
|
||
|
||
::: tip 还有疑问?
|
||
总的来说,就是通过重新定义 `css` 样式,用来覆盖 [element-plus](https://element-plus.gitee.io/#/zh-CN/component/changelog) 默认的样式,从而实现全局主题变色。
|
||
:::
|
||
|
||
## 其它方法实现全局主题
|
||
|
||
- 参考 `花裤衩大佬`:[手摸手,带你用vue撸后台 系列三(实战篇)](https://segmentfault.com/a/1190000009762198#articleHeader2)
|
||
- vue-element-admin:[https://github.com/PanJiaChen/vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
|
||
|
||
|