动态控制主题样式
parent
f95ee72676
commit
dd02f47d82
@ -0,0 +1,25 @@
|
|||||||
|
// 动态更新antd主题颜色
|
||||||
|
const path = require('path');
|
||||||
|
const { generateTheme } = require('antd-theme-generator');
|
||||||
|
const options = {
|
||||||
|
antDir: path.join(__dirname, './node_modules/ant-design-vue'), //依赖位置
|
||||||
|
// stylesDir: path.join(__dirname, './src/style'), //处理style下所有less
|
||||||
|
varFile: path.join(__dirname, './src/style/antd-variables.less'), //antd全局变量
|
||||||
|
themeVariables: [
|
||||||
|
'@primary-color',
|
||||||
|
'@secondary-color',
|
||||||
|
'@text-color',
|
||||||
|
'@text-color-secondary',
|
||||||
|
'@heading-color',
|
||||||
|
'@layout-body-background',
|
||||||
|
'@btn-primary-bg',
|
||||||
|
'@layout-header-background'
|
||||||
|
], // 指定所有我们自定义的需要切换的样式变量。
|
||||||
|
outputFilePath: path.join(__dirname, './public/antd_color.less'), // 输出样式
|
||||||
|
}
|
||||||
|
generateTheme(options).then(() => {
|
||||||
|
console.log('Theme generated successfully');
|
||||||
|
}).catch(error => {
|
||||||
|
console.log('Error', error);
|
||||||
|
});
|
||||||
|
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
server {
|
||||||
|
listen 9007;
|
||||||
|
server_name localhost;
|
||||||
|
client_max_body_size 90m;
|
||||||
|
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://localhost:8099/api;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /{
|
||||||
|
root D:\hzleaper_auto_install\logistics_web_package;
|
||||||
|
index index.html index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/node {
|
||||||
|
proxy_pass http://127.0.0.1:8117;
|
||||||
|
rewrite "^/api/node/(.*)$" /$1 break;
|
||||||
|
}
|
||||||
|
location /api/pic {
|
||||||
|
alias d:\data\media\\;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/mp4 {
|
||||||
|
alias d:\\data\mp4\\;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,12 @@
|
|||||||
|
export default {
|
||||||
|
updateStylesAPI: {
|
||||||
|
url: '/node/styles/update',
|
||||||
|
name: '更新标题菜单样式',
|
||||||
|
method: 'POST'
|
||||||
|
},
|
||||||
|
getStylesAPI: {
|
||||||
|
url: '/node/default_css.json',
|
||||||
|
name: '获取标题菜单样式',
|
||||||
|
method: 'GET'
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
import {
|
||||||
|
ColorPicker, // 颜色选择器
|
||||||
|
Form,
|
||||||
|
FormItem
|
||||||
|
} from 'element-ui';
|
||||||
|
import 'element-ui/lib/theme-chalk/index.css';
|
||||||
|
Vue.use(ColorPicker);
|
||||||
|
Vue.use(Form);
|
||||||
|
Vue.use(FormItem);
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import less from 'less'
|
||||||
|
export default {
|
||||||
|
...less,
|
||||||
|
async: false, // 是否同步
|
||||||
|
env: 'production', // 环境
|
||||||
|
};
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import less from './less';
|
||||||
|
// 更换antd主题色
|
||||||
|
export const changeTheme = (color) => {
|
||||||
|
console.log(less, color);
|
||||||
|
less
|
||||||
|
.modifyVars({
|
||||||
|
'@primary-color': color,
|
||||||
|
'@link-color': color,
|
||||||
|
'@btn-primary-bg': color
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log('antd主题颜色成功')
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('antd主题颜色失败')
|
||||||
|
console.error(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
const vue = new Vue();
|
||||||
|
import api from '@/plugins/axios/index'
|
||||||
|
const { httpNodeApi } = api;
|
||||||
|
import axios from "axios";
|
||||||
|
import {changeTheme} from '@/plugins/themePicker'
|
||||||
|
const store = {
|
||||||
|
state: {
|
||||||
|
data:{
|
||||||
|
"theme":{
|
||||||
|
"primary-color":"rgba(184, 68, 13, 1)"
|
||||||
|
},
|
||||||
|
"title":{
|
||||||
|
"text":"ROBO垛机视觉系统",
|
||||||
|
"style":{
|
||||||
|
"color":"rgba(255, 255, 255, 1)",
|
||||||
|
"background-color":"rgba(163, 60, 12, 1)",
|
||||||
|
"font-size":"24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"menu":{
|
||||||
|
"default":{
|
||||||
|
"color":"rgba(230, 224, 224, 1)",
|
||||||
|
"background-color":"rgba(163, 60, 12, 1)"
|
||||||
|
},
|
||||||
|
"select":{
|
||||||
|
"color":"rgba(255, 255, 255, 1)",
|
||||||
|
"background-color":"rgba(184, 68, 13, 1)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mutations:{
|
||||||
|
UPDATE_STYLES(state, data) {
|
||||||
|
// for(let key in data) {
|
||||||
|
// // state[key] = data[key];
|
||||||
|
// vue.$set(state, key, data[key])
|
||||||
|
// }
|
||||||
|
state.data = data;
|
||||||
|
// 改变主题颜色
|
||||||
|
changeTheme(data.theme['primary-color']);
|
||||||
|
// setItem(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 更新样式
|
||||||
|
async updateStyles({commit}, data) {
|
||||||
|
console.log(Vue.prototype.$api);
|
||||||
|
commit('UPDATE_STYLES', data);
|
||||||
|
await httpNodeApi.updateStylesAPI({data})
|
||||||
|
},
|
||||||
|
// 获取样式
|
||||||
|
async getStyles({commit}){
|
||||||
|
console.log('获取样式');
|
||||||
|
const data = await axios.get('/api/node/default_css.json');
|
||||||
|
commit('UPDATE_STYLES', data.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 初始加载时默认更新一次主题
|
||||||
|
changeTheme(store.state.data.theme['primary-color']);
|
||||||
|
export default store;
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
// @import "ant-design-vue/lib/style/themes/default.less";
|
||||||
|
@primary-color: #1890ff; // 全局主色
|
||||||
|
@link-color: #1890ff; // 链接色
|
||||||
|
@success-color: #52c41a; // 成功色
|
||||||
|
@warning-color: #faad14; // 警告色
|
||||||
|
@error-color: #f5222d; // 错误色
|
||||||
|
@font-size-base: 14px; // 主字号
|
||||||
|
@heading-color: rgba(0, 0, 0, 0.85); // 标题色
|
||||||
|
@text-color: rgba(0, 0, 0, 0.65); // 主文本色
|
||||||
|
@text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
|
||||||
|
@disabled-color: rgba(0, 0, 0, 0.25); // 失效色
|
||||||
|
@border-radius-base: 4px; // 组件/浮层圆角
|
||||||
|
@border-color-base: #d9d9d9; // 边框色
|
||||||
|
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // 浮层阴影
|
||||||
|
|
||||||
|
//:export {
|
||||||
|
// primary-color: @primary-color;
|
||||||
|
//}
|
||||||
|
:root {
|
||||||
|
--PC: @primary-color;
|
||||||
|
}
|
||||||
|
.primary-color{
|
||||||
|
color:@primary-color
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<el-color-picker
|
||||||
|
show-alpha
|
||||||
|
size="medium"
|
||||||
|
:value="color"
|
||||||
|
:predefine="predefineColors"
|
||||||
|
@change="val => $emit('change', val)"
|
||||||
|
>
|
||||||
|
</el-color-picker>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SelectColor",
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
color: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
model: {
|
||||||
|
prop: 'color',
|
||||||
|
event: 'change'
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
predefineColors: [
|
||||||
|
'#ff4500',
|
||||||
|
'#ff8c00',
|
||||||
|
'#ffd700',
|
||||||
|
'#90ee90',
|
||||||
|
'#00ced1',
|
||||||
|
'#1e90ff',
|
||||||
|
'#c71585',
|
||||||
|
'rgba(255, 69, 0, 0.68)',
|
||||||
|
'rgb(255, 120, 0)',
|
||||||
|
'hsv(51, 100, 98)',
|
||||||
|
'hsva(120, 40, 94, 0.5)',
|
||||||
|
'hsl(181, 100%, 37%)',
|
||||||
|
'hsla(209, 100%, 56%, 0.73)',
|
||||||
|
'#c7158577'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
},
|
||||||
|
methods: {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.SelectColor {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="StylesMenu">
|
||||||
|
<p>默认</p>
|
||||||
|
<el-form-item label="字体颜色">
|
||||||
|
<select-color v-model="form.default.color"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="背景颜色">
|
||||||
|
<select-color v-model="form.default['background-color']"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
<p>选中后</p>
|
||||||
|
<el-form-item label="字体颜色">
|
||||||
|
<select-color v-model="form.select.color"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="背景颜色">
|
||||||
|
<select-color v-model="form.select['background-color']"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SelectColor from "./SelectColor";
|
||||||
|
export default {
|
||||||
|
name: "StylesMenu",
|
||||||
|
components: {SelectColor},
|
||||||
|
props: {
|
||||||
|
form:{}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
},
|
||||||
|
methods: {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.StylesMenu {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<div class="StylesTheme">
|
||||||
|
<el-form-item label="主题颜色">
|
||||||
|
<select-color v-model="form['primary-color']"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SelectColor from "./SelectColor";
|
||||||
|
export default {
|
||||||
|
name: "StylesTheme",
|
||||||
|
components: {
|
||||||
|
SelectColor
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
form:{}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
},
|
||||||
|
methods: {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.StylesTheme {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<div class="styles-title">
|
||||||
|
<el-form-item label="标题文字" prop="title.text" :rules="{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }">
|
||||||
|
<a-input v-model="form.text" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字体颜色">
|
||||||
|
<select-color v-model="form.style.color"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="背景颜色">
|
||||||
|
<select-color v-model="form.style['background-color']"></select-color>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <a-form-item label="style">-->
|
||||||
|
<!--<!– json编辑器–>-->
|
||||||
|
<!-- <vue-json-editor-->
|
||||||
|
<!-- v-model="form.style"-->
|
||||||
|
<!-- :mode="'code'"-->
|
||||||
|
<!-- lang="zh"-->
|
||||||
|
<!-- @json-change="onJsonChange"-->
|
||||||
|
<!-- @has-error="onError">-->
|
||||||
|
<!-- </vue-json-editor>-->
|
||||||
|
<!-- </a-form-item>-->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SelectColor from "./SelectColor";
|
||||||
|
// import vueJsonEditor from 'vue-json-editor'
|
||||||
|
export default {
|
||||||
|
name: "StylesTitle",
|
||||||
|
components: {
|
||||||
|
SelectColor
|
||||||
|
// vueJsonEditor
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
form: {}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onJsonChange(data) {
|
||||||
|
if(typeof data === "object") {
|
||||||
|
this.form.style = data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError(err) {
|
||||||
|
// console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.styles-title /deep/{
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<div class="index">
|
||||||
|
<el-form :model="formData" ref="ruleForm" label-width="100px" class="demo-ruleForm">
|
||||||
|
<a-collapse v-model="activeKey">
|
||||||
|
<a-collapse-panel key="0" header="主题">
|
||||||
|
<styles-theme :form.sync="formData.theme"></styles-theme>
|
||||||
|
</a-collapse-panel>
|
||||||
|
<a-collapse-panel key="1" header="标题">
|
||||||
|
<styles-title :form.sync="formData.title"></styles-title>
|
||||||
|
</a-collapse-panel>
|
||||||
|
<a-collapse-panel key="2" header="菜单">
|
||||||
|
<styles-menu :form.sync="formData.menu"></styles-menu>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
|
<el-form-item>
|
||||||
|
<span style="float: right">
|
||||||
|
<a-button type="primary" @click="handleSubmit()" style="margin-right: 10px">
|
||||||
|
保存
|
||||||
|
</a-button>
|
||||||
|
<a-button type="info" @click="init()">
|
||||||
|
重置
|
||||||
|
</a-button>
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapActions } from 'vuex'
|
||||||
|
import StylesTitle from "./StylesTitle";
|
||||||
|
import StylesMenu from "./StylesMenu";
|
||||||
|
import StylesTheme from "./StylesTheme";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "index",
|
||||||
|
components: {StylesTheme, StylesMenu, StylesTitle},
|
||||||
|
props: {},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['styles']),
|
||||||
|
watchStyles() {
|
||||||
|
return JSON.stringify(this.styles);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
watchStyles() {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeKey: ['0', '1', '2'],
|
||||||
|
formData: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
console.log(this.styles);
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(['updateStyles']),
|
||||||
|
init() {
|
||||||
|
console.log('init');
|
||||||
|
this.formData = JSON.parse(JSON.stringify(this.styles));
|
||||||
|
},
|
||||||
|
// 提交
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.ruleForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.updateStyles(this.formData);
|
||||||
|
} else {
|
||||||
|
console.log('error submit!!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.index /deep/{
|
||||||
|
width: 70%;
|
||||||
|
margin: auto;
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.jsoneditor-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue