未验证 提交 7e8eddf1 编写于 作者: Mr.奇淼('s avatar Mr.奇淼( 提交者: GitHub

Merge pull request #552 from bypanghu/master

新增侧边栏修改主题
<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>
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
},
computed: {
defaultTheme() {
return this.$store.state.user.theme
}
},
watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
},
immediate: true
},
async theme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const $message = this.$message({
message: '修改主题色中',
customClass: 'theme-message',
type: 'success',
duration: 0,
iconClass: 'el-icon-loading'
})
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$emit('change', val)
$message.close()
}
},
methods: {
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</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>
......@@ -58,7 +58,8 @@ import {
Upload,
Progress,
MessageBox,
Image
Image,
ColorPicker
} from 'element-ui'
Vue.use(Button)
......@@ -110,7 +111,7 @@ Vue.use(Progress)
Vue.use(Scrollbar)
Vue.use(Loading.directive)
Vue.use(Image)
Vue.use(ColorPicker)
Vue.prototype.$loading = Loading.service
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
......
import { login } from '@/api/user'
import { jsonInBlacklist } from '@/api/jwt'
import router from '@/router/index'
import variables from '@/style/element_visiable.scss'
export const user = {
namespaced: true,
state: {
......@@ -8,7 +9,9 @@ export const user = {
uuid: '',
nickName: '',
headerImg: '',
authority: ''
authority: '',
sideMode : 'dark',
theme: variables.colorPrimary,
},
token: ''
},
......@@ -38,6 +41,12 @@ export const user = {
state.userInfo = { ...state.userInfo,
...userInfo
}
},
CHANGETHEME: (state, value) => {
state.theme = value
},
CHANGESIDEMODE: (state ,val) => {
state.sideMode = val
}
},
actions: {
......@@ -64,6 +73,12 @@ export const user = {
if (res.code === 0) {
commit('LoginOut')
}
},
changeTheme({ commit }, data) {
commit('CHANGETHEME', data)
},
changeSideMode({ commit },data) {
commit('CHANGESIDEMODE',data)
}
},
getters: {
......@@ -72,6 +87,9 @@ export const user = {
},
token(state) {
return state.token
},
getSideMode(state) {
return state.sideMode
}
}
......
/* 改变主题色变量 */
$--color-primary: #1890ff;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
:export {
colorPrimary: $--color-primary
}
\ No newline at end of file
......@@ -6,9 +6,10 @@
:collapse="isCollapse"
:collapse-transition="true"
:default-active="active"
active-text-color="#fff"
:active-text-color="$store.getters['user/getSideMode'] === 'dark' ? '#1890ff' : '#1890ff'"
:background-color="$store.getters['user/getSideMode'] === 'dark' ? '#191a23 ' : '#fff'"
class="el-menu-vertical"
text-color="rgb(191, 203, 217)"
text-color="#999"
unique-opened
@select="selectMenuItem"
>
......
......@@ -3,9 +3,9 @@
<el-container :class="[isSider?'openside':'hideside',isMobile ? 'mobile': '']">
<el-row :class="[isShadowBg?'shadowBg':'']" @click.native="changeShadow()" />
<el-aside class="main-cont main-left">
<div class="tilte">
<div class="tilte" :class="$store.getters['user/getSideMode']">
<img alt class="logoimg" :src="$GIN_VUE_ADMIN.appLogo">
<h2 v-if="isSider" class="tit-text">{{ $GIN_VUE_ADMIN.appName }}</h2>
<h2 v-if="isSider" class="tit-text" :class="$store.getters['user/getSideMode']">{{ $GIN_VUE_ADMIN.appName }}</h2>
</div>
<Aside class="aside" />
</el-aside>
......@@ -74,6 +74,7 @@
<router-view v-if="!$route.meta.keepAlive && reloadFlag" v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" />
</transition>
<BottomInfo />
<setting />
</el-main>
</el-container>
......@@ -88,6 +89,7 @@ import Search from '@/view/layout/search/search'
import BottomInfo from '@/view/layout/bottomInfo/bottomInfo'
import { mapGetters, mapActions } from 'vuex'
import CustomPic from '@/components/customPic'
import Setting from './setting'
export default {
name: 'Layout',
components: {
......@@ -96,7 +98,8 @@ export default {
Screenfull,
Search,
BottomInfo,
CustomPic
CustomPic,
Setting
},
data() {
return {
......@@ -339,4 +342,12 @@ export default {
// justify-content: center;
// align-items: center;
// }
.dark{
background-color: #191a23 !important;
color: #fff !important;
}
.light{
background-color: #fff !important;
color: #000 !important;
}
</style>
<template>
<div>
<el-button type="primary" class="drawer-container" icon="el-icon-setting" @click="showSettingDrawar" />
<el-drawer
title="系统配置"
:visible.sync="drawer"
:direction="direction"
:before-close="handleClose"
>
<div class="setting_body">
<div class="setting_card">
<div class="setting_title">侧边栏主题</div>
<div class="setting_content">
<div class="item" @click="chageMode('light')">
<i v-if="sideMode === 'light'" class="el-icon-check check" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/NQ%24zoisaD2/jpRkZQMyYRryryPNtyIC.svg">
</div>
<div class="item" @click="chageMode('dark')">
<i v-if="sideMode === 'dark'" class="el-icon-check check" />
<img src="https://gw.alipayobjects.com/zos/antfincdn/XwFOFbLkSM/LCkqqYNmvBEbokSDscrm.svg">
</div>
</div>
</div>
<!-- <div class="setting_card">-->
<!-- <div class="setting_title">主题色</div>-->
<!-- <div class="">-->
<!-- <theme-change style="width: 30px;height: 30px;margin-top: 20px" @change="themeChange" />-->
<!-- </div>-->
<!-- </div>-->
</div>
</el-drawer>
</div>
</template>
<script>
import themeChange from '@/components/themeChange'
export default {
data() {
return {
drawer: false,
direction: 'rtl',
sideMode: 'dark'
}
},
components: {
themeChange
},
methods: {
handleClose() {
this.drawer = false
},
showSettingDrawar() {
this.drawer = true
},
chageMode(e) {
this.sideMode = e
this.$store.dispatch('user/changeSideMode',e)
},
themeChange(val) {
this.$store.dispatch('user/changeTheme', val)
}
}
}
</script>
<style lang="scss" scoped>
.drawer-container {
position: absolute;
right: 0;
top: 20%;
height: 40px;
width: 40px;
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
color: #fff;
border-radius: 4px 0 0 4px;
cursor: pointer;
-webkit-box-shadow: inset 0 0 6px rgb(0 ,0 ,0, 10%);
}
.setting_body{
padding: 20px;
.setting_card{
margin-bottom: 20px;
}
.setting_content{
margin-top: 20px;
display: flex;
.item{
position: relative;
display: flex;
align-items: center;
justify-content: center;
.check{
position: absolute;
font-size: 20px;
color: #00afff;
}
img{
margin-right: 20px;
}
}
}
}
</style>
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册