Vue2:切换主题功能
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
1:前提准备
1.需要安相关的依赖
npm install style-resources-loader -D
npm install vue-cli-plugin-style-resources-loader -D
2.在这里我使用的less,所以没有安装less相对应的依赖的话需要安装less
npm install less-loader@5.0.0 --save
npm install less --save
2:具体实现
1.创建全局的 less 变量文件:variables.less
//导航栏
@navbackground :var(--navbackground,'#001529'); // var('变量名','默认值')
//tab
@tabbackground :var(--tabbackground,'black');
@tabfontcolor : var(--tabfontcolor,'black');
//主题颜色
@contentbackground :var(--contentbackground,'#1890ff');
@contenthouverbackground :var(--contenthouverbackground,'#e6f7ff');
@buttonhouverbackground : var(--buttonhouverbackground,'#fff');
//抛出自己定义的变量
:export{
name: 'less';
navbackground:@navbackground;
tabbackground:@tabbackground;
contentbackground:@contentbackground;
contenthouverbackground:@contenthouverbackground;
tabfontcolor : @tabfontcolor;
buttonhouverbackground : @buttonhouverbackground;
}
2.定义主题默认对应的颜色 :model.js
export const themes = {
//默认nav导航栏
default: {
navbackground:'#001529'
},
dark: {
navbackground:'#ffffff'
},
//默认头部
headerdefault:{
tabbackground:'#ffffff',
tabfontcolor:'#000'
},
headerdedark:{
tabbackground:'#000000',
tabfontcolor:'#fff'
},
headerthreme:{
tabbackground : "#1890ff",
tabfontcolor:'#fff'
},
//默认主题颜色
themebackground : {
contentbackground: '#1890ff',
contenthouverbackground : "#e6f7ff",
tabfontcolor:'#fff'
},
};
2.配置解析less变量设置:在vue.config.json文件中找到 mudule.exprots
module.exports = defineConfig({
publicPath: process.env.NODE_ENV === "production" ? "./" : "./",
// 输出文件目录
outputDir: 'dist',
pluginOptions: {
"style-resources-loader": {
preProcessor: "less",
patterns: [
// 这个是加上自己的路径,不能使用(如下:alias)中配置的别名路径 需要解析的less文件
path.resolve(__dirname, "./src/assets/css/variables.less"),
],
},
},
})
3.点击不同的主题颜色,调用方法改变原来的less变量值,直接吧主题模块代码
<template>
<div class="theme-content">
<div class="broadside" >
<div v-for="(item ,index) in broadsideList" >
<el-tooltip class="item" effect="dark" :content="item.text" placement="top">
<div @click="handelBroadside(index,item)" :class="item.class+'-'+item.type" style="margin-left:10px" >
<div class="left"></div>
<div class="rigth">
<div class="rigth-top"></div>
<div class="rigth-bottom">
<i class="el-icon-check" v-if="item.isshow"></i>
</div>
</div>
</div>
</el-tooltip>
</div>
</div>
<div class="topbar">
<!-- 第二行 -->
<div v-for="(item ,index) in TopBarList">
<el-tooltip class="item" effect="dark" :content="item.text" placement="top">
<div @click="handelTopBar(index,item)" :class="item.class+'-'+item.type" style="margin-left:10px">
<div class="left"></div>
<div class="rigth">
<div class="rigth-top"></div>
<div class="rigth-bottom">
<i class="el-icon-check" v-if="item.isshow"></i>
</div>
</div>
</div>
</el-tooltip>
</div>
</div>
<!-- 第三行 -->
<div class="colordisc">
<div v-for="(item,index) in colordiscList">
<el-tooltip class="item" effect="dark" :content="item.text" placement="top">
<div :style="{'background':item.color}" class="disc" @click="handelcolordisc(index,item)">
<i class="el-icon-check" v-if="item.isshow"></i>
</div>
</el-tooltip>
</div>
</div>
</div>
</template>
<script>
import { setTheme } from "@/assets/js/theme";
import Vue from 'vue'
export default{
data(){
return{
broadsideList:[
{
class:'broadside',
text:'暗色側邊欄',
type:'left',
isshow:true,
status:'default',//进入默认选中的查找数据
},
{
class:'broadside',
text:'亮色側邊欄',
type:'rigth',
isshow:false,
status:'dark',//进入默认选中的查找数据
},
],
TopBarList:[
{
class:'topbar',
text:'亮色頂欄',
type:'white',
isshow:true,
status:'headerdefault',//进入默认选中的查找数据
},
{
class:'topbar',
text:'暗色頂欄',
type:'black',
isshow:false,
status:'headerdedark',//进入默认选中的查找数据
},{
class:'topbar',
text:'主色頂欄',
type:'theme',
isshow:false,
status:'headerthreme',//进入默认选中的查找数据
}
],
colordiscList:[
{
color:'#1890ff',//进入默认选中的查找数据
text:'拂曉藍',
isshow:true,
},
{
color:'#5f80c7',//进入默认选中的查找数据
text:'薄暮',
isshow:false,
},
{
color:'#faad14',//进入默认选中的查找数据
text:'日暮',
isshow:false,
},
{
color:'#f5686f',//进入默认选中的查找数据
text:'火山',
isshow:false,
},
{
color:'#9266f9',//进入默认选中的查找数据
text:'醬紫',
isshow:false,
},
{
color:'#2bccce',//进入默认选中的查找数据
text:'明青',
isshow:false,
},
{
color:'#33cc99',//进入默认选中的查找数据
text:'極光綠',
isshow:false,
},
{
color:'#32a2d4',//进入默认选中的查找数据
text:'極客藍',
isshow:false,
},
],
headerthreme:'',
clickheader:'',//点击的是哪个类型
}
},
mounted(){
//默认选中
if(sessionStorage.getItem('threme-nav')){
this.broadsideList.filter(function(item){
if(item.status !== sessionStorage.getItem('threme-nav'))
{
item.isshow = false
}else{
item.isshow = true
}
})
}
if(sessionStorage.getItem('threme-header')){
this.TopBarList.filter(function(item){
if(item.status !== sessionStorage.getItem('threme-header'))
{
item.isshow = false
}else{
item.isshow = true
}
})
}
if(sessionStorage.getItem('threme-color')){
this.colordiscList.filter(function(item){
if(item.color !== sessionStorage.getItem('threme-color'))
{
item.isshow = false
}else{
item.isshow = true
}
})
}
},
methods:{
handelBroadside(index,item){
this.broadsideList.filter(i=> { if(i.isshow === true){
i.isshow = false
item.isshow = true
}})
switch (index) {
case 0:
setTheme("default")
sessionStorage.setItem('threme-nav','default')
break;
case 1:
setTheme("dark")
sessionStorage.setItem('threme-nav','dark')
break;
}
},
handelTopBar(index,item){
this.TopBarList.filter(i=> { if(i.isshow === true){
i.isshow = false
item.isshow = true
}})
switch (index) {
case 0:
setTheme("headerdefault")
sessionStorage.setItem('threme-header','headerdefault')
break;
case 1:
setTheme("headerdedark")
sessionStorage.setItem('threme-header','headerdedark')
break;
case 2:
setTheme("headerthreme")
sessionStorage.setItem('threme-header','headerthreme')
break;
}
},
handelcolordisc(index,item){
this.colordiscList.filter(i=> { if(i.isshow === true){
i.isshow = false
item.isshow = true
}})
sessionStorage.setItem('threme-color',item.color)
if(sessionStorage.getItem('threme-header') === 'headerthreme'){
setTheme("headerthreme")
}
Vue.prototype.bus.$emit('color',item.color)
},
}
}
</script>
<style lang="less" scoped>
.theme-content{
width: 100%;
height: 400px;
.broadside,.topbar{
width: 100%;
margin: auto;
height: 80px;
display: flex;
.broadside-left,.broadside-rigth,.topbar-white,.topbar-black,.topbar-theme{
width: 70px;
height: 50px;
overflow: hidden;
border-radius: 5px;
display: flex;
flex-direction: row;
box-shadow: 1px 1px 5px #e4e4e4;
.left{
width: 30%;
height: 100%;
background: #001529;
}
.rigth{
width: 70%;
height: 100%;
background: cadetblue;
.rigth-top{
width: 100%;
height: 20%;
}
.rigth-top{
width: 100%;
height: 20%;
background: #ffffff;
}
.rigth-bottom{
width: 100%;
height: 80%;
background: #f0f2f5;
}
}
}
//左侧栏深色 end
.broadside-rigth{
.left{
width: 30%;
height: 100%;
background: #ffffff;
}
.rigth{
width: 70%;
height: 100%;
background: cadetblue;
.rigth-top{
width: 100%;
height: 20%;
}
.rigth-top{
width: 100%;
height: 20%;
background: #ffffff;
}
.rigth-bottom{
width: 100%;
height: 80%;
background: #f0f2f5;
}
}
}
//左侧栏白色 end
}
}
.rigth-bottom{
color: #63b6dc;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
}
// 第二行第一个
.topbar-white{
.left{
background: #ffffff !important;
}
}
// 第二行第二个
.topbar-black{
.left{
background: #ffffff !important;
}
.rigth-top{
width: 100%;
height: 20%;
background: black !important;
}
}
// 第二行第三个
.topbar-theme{
.left{
background: #ffffff !important;
}
.rigth-top{
width: 100%;
height: 20%;
background: @contentbackground !important;
}
}
// 色盘
.colordisc{
width: 100%;
height: 30px;
display: flex;
justify-content: space-around;
.disc{
width: 20px;
height: 20px;
border-radius: 3px;
line-height: 20px;
text-align: center;
.el-icon-check{
color: white;
font-size: 13px;
}
}
}
</style>
4.主题组件调用的方法
//默认的对象数据
import { themes } from "./model";
import Vue from 'vue'
const changeStyle = (obj) => {
console.log('obj',obj);
for (let key in obj) {
//重新赋值自己之前定义的less变量值
document.getElementsByTagName("body")[0].style.setProperty(`--${key}`, obj[key]);
}
console.log();
};
//切换主题颜色方法
const changeTheme = (data) => {
console.log('主题颜色',data);
for (let key in data) {
//重新赋值自己之前定义的less变量值
document.getElementsByTagName("body")[0].style.setProperty(`--${key}`, data[key]);
}
Vue.prototype.bus.$on('color',val=>{
let data = {}
console.log('val',val);
switch (val) {
case '#1890ff':
data.contentbackground = '#1890ff'
data.contenthouverbackground = '#40a9ff'
data.buttonhouverbackground = '#e6f7ff'//透明的按钮移入背景
changeTheme(data)
break;
case '#5f80c7':
data.contentbackground = '#5f80c7'
data.contenthouverbackground = '#87a2d4'
data.buttonhouverbackground = '#f0f7ff'//透明的按钮移入背景
changeTheme(data)
break;
case '#faad14':
data.contentbackground = '#faad14'
data.contenthouverbackground = '#ffc53d'
data.buttonhouverbackground = '#fffbe6'//透明的按钮移入背景
changeTheme(data)
break;
case '#f5686f':
data.contentbackground = '#f5686f'
data.contenthouverbackground = '#ff9496'
data.buttonhouverbackground = '#fff1f0'//透明的按钮移入背景
changeTheme(data)
break;
case '#9266f9':
data.contentbackground = '#9266f9'
data.contenthouverbackground = '#b691ff'
data.buttonhouverbackground = '#f7f0ff'//透明的按钮移入背景
changeTheme(data)
break;
case '#2bccce':
data.contentbackground = '#2bccce'
data.contenthouverbackground = '#51dbd9'
data.buttonhouverbackground = '#f0fffd'//透明的按钮移入背景
changeTheme(data)
break;
case '#33cc99':
data.contentbackground = '#33cc99'
data.contenthouverbackground = '#59d9aa'
data.buttonhouverbackground = '#f0fff7'//透明的按钮移入背景
changeTheme(data)
break;
case '#32a2d4':
data.contentbackground = '#32a2d4'
data.contenthouverbackground = '#5abae0'
data.buttonhouverbackground = '#f0fdff'//透明的按钮移入背景
changeTheme(data)
break;
}
})
}
//改变主题的方法
export const setTheme = (themeName) => {
let themeConfig = themes[themeName];
//判断点击的是不是 header头部主题类型样式
if(themeName === 'headerthreme'){
themeConfig.tabbackground = sessionStorage.getItem('threme-color')
}
//themeName 传递的是默认值 还是其他值 就是 model.js 中的 default 或者 dark
sessionStorage.setItem("theme", themeName); // 保存主题到本地,下次进入使用该主题
// 如果有主题名称,那么则采用我们定义的主题
//判断传递过来的 themeName 是否存在,如果没存在 themes[themeName]获取不到你想要的数据 就会走else
if (themeConfig) {
sessionStorage.setItem("themeConfig",JSON.stringify(themeConfig)); // 保存主题色到本地
changeStyle(themeConfig); // 改变样式
} else {
changeStyle(themeConfig);
}
};
调用方法更改less变量的值,然后把less变量给对应需要改变颜色的css中就行啦
附上截图
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献12条内容
所有评论(0)