作者 RuoYi

修改主题样式本地读取

1 -<template>  
2 - <el-color-picker  
3 - v-model="theme"  
4 - :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"  
5 - class="theme-picker"  
6 - popper-class="theme-picker-dropdown"  
7 - />  
8 -</template>  
9 -  
10 -<script>  
11 -const version = require('element-ui/package.json').version // element-ui version from node_modules  
12 -const ORIGINAL_THEME = '#409EFF' // default color  
13 -  
14 -export default {  
15 - data() {  
16 - return {  
17 - chalk: '', // content of theme-chalk css  
18 - theme: ''  
19 - }  
20 - },  
21 - computed: {  
22 - defaultTheme() {  
23 - return this.$store.state.settings.theme  
24 - }  
25 - },  
26 - watch: {  
27 - defaultTheme: {  
28 - handler: function(val, oldVal) {  
29 - this.theme = val  
30 - },  
31 - immediate: true  
32 - },  
33 - async theme(val) {  
34 - await this.setTheme(val)  
35 - }  
36 - },  
37 - created() {  
38 - if(this.defaultTheme !== ORIGINAL_THEME) {  
39 - this.setTheme(this.defaultTheme)  
40 - }  
41 - },  
42 -  
43 - methods: {  
44 - async setTheme(val) {  
45 - const oldVal = this.chalk ? this.theme : ORIGINAL_THEME  
46 - if (typeof val !== 'string') return  
47 - const themeCluster = this.getThemeCluster(val.replace('#', ''))  
48 - const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))  
49 -  
50 - const getHandler = (variable, id) => {  
51 - return () => {  
52 - const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))  
53 - const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)  
54 -  
55 - let styleTag = document.getElementById(id)  
56 - if (!styleTag) {  
57 - styleTag = document.createElement('style')  
58 - styleTag.setAttribute('id', id)  
59 - document.head.appendChild(styleTag)  
60 - }  
61 - styleTag.innerText = newStyle  
62 - }  
63 - }  
64 -  
65 - if (!this.chalk) {  
66 - const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`  
67 - await this.getCSSString(url, 'chalk')  
68 - }  
69 -  
70 - const chalkHandler = getHandler('chalk', 'chalk-style')  
71 -  
72 - chalkHandler()  
73 -  
74 - const styles = [].slice.call(document.querySelectorAll('style'))  
75 - .filter(style => {  
76 - const text = style.innerText  
77 - return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)  
78 - })  
79 - styles.forEach(style => {  
80 - const { innerText } = style  
81 - if (typeof innerText !== 'string') return  
82 - style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)  
83 - })  
84 -  
85 - this.$emit('change', val)  
86 - },  
87 -  
88 - updateStyle(style, oldCluster, newCluster) {  
89 - let newStyle = style  
90 - oldCluster.forEach((color, index) => {  
91 - newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])  
92 - })  
93 - return newStyle  
94 - },  
95 -  
96 - getCSSString(url, variable) {  
97 - return new Promise(resolve => {  
98 - const xhr = new XMLHttpRequest()  
99 - xhr.onreadystatechange = () => {  
100 - if (xhr.readyState === 4 && xhr.status === 200) {  
101 - this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')  
102 - resolve()  
103 - }  
104 - }  
105 - xhr.open('GET', url)  
106 - xhr.send()  
107 - })  
108 - },  
109 -  
110 - getThemeCluster(theme) {  
111 - const tintColor = (color, tint) => {  
112 - let red = parseInt(color.slice(0, 2), 16)  
113 - let green = parseInt(color.slice(2, 4), 16)  
114 - let blue = parseInt(color.slice(4, 6), 16)  
115 -  
116 - if (tint === 0) { // when primary color is in its rgb space  
117 - return [red, green, blue].join(',')  
118 - } else {  
119 - red += Math.round(tint * (255 - red))  
120 - green += Math.round(tint * (255 - green))  
121 - blue += Math.round(tint * (255 - blue))  
122 -  
123 - red = red.toString(16)  
124 - green = green.toString(16)  
125 - blue = blue.toString(16)  
126 -  
127 - return `#${red}${green}${blue}`  
128 - }  
129 - }  
130 -  
131 - const shadeColor = (color, shade) => {  
132 - let red = parseInt(color.slice(0, 2), 16)  
133 - let green = parseInt(color.slice(2, 4), 16)  
134 - let blue = parseInt(color.slice(4, 6), 16)  
135 -  
136 - red = Math.round((1 - shade) * red)  
137 - green = Math.round((1 - shade) * green)  
138 - blue = Math.round((1 - shade) * blue)  
139 -  
140 - red = red.toString(16)  
141 - green = green.toString(16)  
142 - blue = blue.toString(16)  
143 -  
144 - return `#${red}${green}${blue}`  
145 - }  
146 -  
147 - const clusters = [theme]  
148 - for (let i = 0; i <= 9; i++) {  
149 - clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))  
150 - }  
151 - clusters.push(shadeColor(theme, 0.1))  
152 - return clusters  
153 - }  
154 - }  
155 -}  
156 -</script>  
157 -  
158 -<style>  
159 -.theme-message,  
160 -.theme-picker-dropdown {  
161 - z-index: 99999 !important;  
162 -}  
163 -  
164 -.theme-picker .el-color-picker__trigger {  
165 - height: 26px !important;  
166 - width: 26px !important;  
167 - padding: 2px;  
168 -}  
169 -  
170 -.theme-picker-dropdown .el-color-dropdown__link-btn {  
171 - display: none;  
172 -}  
173 -</style> 1 +<template>
  2 + <el-color-picker
  3 + v-model="theme"
  4 + :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
  5 + class="theme-picker"
  6 + popper-class="theme-picker-dropdown"
  7 + />
  8 +</template>
  9 +
  10 +<script>
  11 +const ORIGINAL_THEME = '#409EFF' // default color
  12 +
  13 +export default {
  14 + data() {
  15 + return {
  16 + chalk: '', // content of theme-chalk css
  17 + theme: ''
  18 + }
  19 + },
  20 + computed: {
  21 + defaultTheme() {
  22 + return this.$store.state.settings.theme
  23 + }
  24 + },
  25 + watch: {
  26 + defaultTheme: {
  27 + handler: function(val, oldVal) {
  28 + this.theme = val
  29 + },
  30 + immediate: true
  31 + },
  32 + async theme(val) {
  33 + await this.setTheme(val)
  34 + }
  35 + },
  36 + created() {
  37 + if(this.defaultTheme !== ORIGINAL_THEME) {
  38 + this.setTheme(this.defaultTheme)
  39 + }
  40 + },
  41 + methods: {
  42 + async setTheme(val) {
  43 + const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
  44 + if (typeof val !== 'string') return
  45 + const themeCluster = this.getThemeCluster(val.replace('#', ''))
  46 + const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
  47 +
  48 + const getHandler = (variable, id) => {
  49 + return () => {
  50 + const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
  51 + const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
  52 +
  53 + let styleTag = document.getElementById(id)
  54 + if (!styleTag) {
  55 + styleTag = document.createElement('style')
  56 + styleTag.setAttribute('id', id)
  57 + document.head.appendChild(styleTag)
  58 + }
  59 + styleTag.innerText = newStyle
  60 + }
  61 + }
  62 +
  63 + if (!this.chalk) {
  64 + const url = `/styles/theme-chalk/index.css`
  65 + await this.getCSSString(url, 'chalk')
  66 + }
  67 +
  68 + const chalkHandler = getHandler('chalk', 'chalk-style')
  69 + chalkHandler()
  70 +
  71 + const styles = [].slice.call(document.querySelectorAll('style'))
  72 + .filter(style => {
  73 + const text = style.innerText
  74 + return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
  75 + })
  76 + styles.forEach(style => {
  77 + const { innerText } = style
  78 + if (typeof innerText !== 'string') return
  79 + style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
  80 + })
  81 +
  82 + this.$emit('change', val)
  83 + },
  84 +
  85 + updateStyle(style, oldCluster, newCluster) {
  86 + let newStyle = style
  87 + oldCluster.forEach((color, index) => {
  88 + newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
  89 + })
  90 + return newStyle
  91 + },
  92 +
  93 + getCSSString(url, variable) {
  94 + return new Promise(resolve => {
  95 + const xhr = new XMLHttpRequest()
  96 + xhr.onreadystatechange = () => {
  97 + if (xhr.readyState === 4 && xhr.status === 200) {
  98 + this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
  99 + resolve()
  100 + }
  101 + }
  102 + xhr.open('GET', url)
  103 + xhr.send()
  104 + })
  105 + },
  106 +
  107 + getThemeCluster(theme) {
  108 + const tintColor = (color, tint) => {
  109 + let red = parseInt(color.slice(0, 2), 16)
  110 + let green = parseInt(color.slice(2, 4), 16)
  111 + let blue = parseInt(color.slice(4, 6), 16)
  112 +
  113 + if (tint === 0) { // when primary color is in its rgb space
  114 + return [red, green, blue].join(',')
  115 + } else {
  116 + red += Math.round(tint * (255 - red))
  117 + green += Math.round(tint * (255 - green))
  118 + blue += Math.round(tint * (255 - blue))
  119 +
  120 + red = red.toString(16)
  121 + green = green.toString(16)
  122 + blue = blue.toString(16)
  123 +
  124 + return `#${red}${green}${blue}`
  125 + }
  126 + }
  127 +
  128 + const shadeColor = (color, shade) => {
  129 + let red = parseInt(color.slice(0, 2), 16)
  130 + let green = parseInt(color.slice(2, 4), 16)
  131 + let blue = parseInt(color.slice(4, 6), 16)
  132 +
  133 + red = Math.round((1 - shade) * red)
  134 + green = Math.round((1 - shade) * green)
  135 + blue = Math.round((1 - shade) * blue)
  136 +
  137 + red = red.toString(16)
  138 + green = green.toString(16)
  139 + blue = blue.toString(16)
  140 +
  141 + return `#${red}${green}${blue}`
  142 + }
  143 +
  144 + const clusters = [theme]
  145 + for (let i = 0; i <= 9; i++) {
  146 + clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
  147 + }
  148 + clusters.push(shadeColor(theme, 0.1))
  149 + return clusters
  150 + }
  151 + }
  152 +}
  153 +</script>
  154 +
  155 +<style>
  156 +.theme-message,
  157 +.theme-picker-dropdown {
  158 + z-index: 99999 !important;
  159 +}
  160 +
  161 +.theme-picker .el-color-picker__trigger {
  162 + height: 26px !important;
  163 + width: 26px !important;
  164 + padding: 2px;
  165 +}
  166 +
  167 +.theme-picker-dropdown .el-color-dropdown__link-btn {
  168 + display: none;
  169 +}
  170 +</style>
@@ -9,7 +9,7 @@ import { isRelogin } from '@/utils/request' @@ -9,7 +9,7 @@ import { isRelogin } from '@/utils/request'
9 9
10 NProgress.configure({ showSpinner: false }) 10 NProgress.configure({ showSpinner: false })
11 11
12 -const whiteList = ['/login', '/register', '/register*', '/register/*'] 12 +const whiteList = ['/login', '/register']
13 13
14 const isWhiteList = (path) => { 14 const isWhiteList = (path) => {
15 return whiteList.some(pattern => isPathMatch(pattern, path)) 15 return whiteList.some(pattern => isPathMatch(pattern, path))