1.vue仿照snowy 配置,如下图:

2.代码实现
<template>
<div class="theme-settings">
<!-- 导航栏 -->
<div class="nav-bar">
<el-breadcrumb separator="/">
<el-breadcrumb-item>导航设置</el-breadcrumb-item>
<el-breadcrumb-item>导航菜单布局</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- 设置区域 -->
<div class="settings-section">
<!-- 整体风格设置 -->
<div class="setting-item">
<span class="label">整体风格设置</span>
<div class="style-options">
<div
v-for="(style, index) in styles"
:key="index"
:class="{ 'style-block': true, selected: selectedStyle === style.value }"
@click="selectStyle(style.value)"
>
<div :class="['style-icon', style.class]">
<div :class="['header-bar', style.headerClass]"></div>
</div>
</div>
</div>
</div>
<!-- 整体界面布局 -->
<div class="setting-item">
<span class="label">整体界面布局</span>
<div class="layout-options">
<div
v-for="(layout, index) in layouts"
:key="index"
:class="{ 'layout-block': true, selected: selectedLayout === layout.value }"
@click="selectLayout(layout.value)"
>
<div :class="['layout-icon', layout.class]">
<div :class="['header-bar', layout.headerClass]"></div>
</div>
</div>
</div>
</div>
<!-- 主题设置 -->
<h3>主题设置 <el-button type="text" size="small" @click="resetTheme">恢复默认(黑灰)</el-button></h3>
<!-- 主题色 -->
<div class="setting-item">
<span class="label">主题色</span>
<div class="color-picker">
<div
v-for="(color, index) in themeColors"
:key="index"
:style="{ backgroundColor: color }"
:class="{ 'color-block': true, selected: selectedThemeColor === color }"
@click="selectThemeColor(color)"
></div>
</div>
</div>
<!-- 页面公用主色 -->
<div class="setting-item">
<span class="label">页面公用主色</span>
<el-switch v-model="useCommonMainColor"></el-switch>
</div>
<!-- 页面公用背景色 -->
<div class="setting-item">
<span class="label">页面公用背景色</span>
<el-switch v-model="useCommonBgColor"></el-switch>
</div>
<!-- 侧边栏 -->
<div class="setting-item">
<span class="label">侧边栏</span>
<el-switch v-model="showSidebar"></el-switch>
</div>
<!-- 侧边栏展开 -->
<div class="setting-item">
<span class="label">侧边栏展开</span>
<el-switch v-model="expandSidebar"></el-switch>
</div>
<!-- 变更模块展开方式 -->
<div class="setting-item">
<span class="label">变更模块展开方式</span>
<el-switch v-model="changeModuleExpand"></el-switch>
</div>
<!-- 变更用户小卡片 -->
<div class="setting-item">
<span class="label">变更用户小卡片</span>
<el-switch v-model="changeUserCard"></el-switch>
</div>
<!-- 页面权限角色 -->
<div class="setting-item">
<span class="label">页面权限角色</span>
<el-switch v-model="enablePageRole"></el-switch>
</div>
<!-- 页面权限 -->
<div class="setting-item">
<span class="label">页面权限</span>
<el-switch v-model="enablePagePermission"></el-switch>
</div>
<!-- 提示信息 -->
<div class="tip">
<el-alert
title="提示:切换主题需重新登录,开发需先在 config/index.js 中配置默认值,否则不会生效"
type="warning"
:closable="false"
></el-alert>
</div>
<!-- 操作按钮 -->
<div class="actions">
<el-button type="primary" @click="saveSettings">提交</el-button>
<el-button @click="resetSettings">重置</el-button>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// 整体风格设置选项
styles: [
{ value: "style1", class: "style1", headerClass: "header-dark" },
{ value: "style2", class: "style2", headerClass: "header-light" },
{ value: "style3", class: "style3", headerClass: "header-dark" },
],
selectedStyle: "style3", // 默认选中第三个
// 整体界面布局选项
layouts: [
{ value: "layout1", class: "layout1", headerClass: "header-dark" },
{ value: "layout2", class: "layout2", headerClass: "header-dark" },
{ value: "layout3", class: "layout3", headerClass: "header-dark" },
],
selectedLayout: "layout1", // 默认选中第一个
// 主题色
themeColors: [
"#FF0000", // 红
"#FF69B4", // 粉
"#00CED1", // 青
"#00FF00", // 绿
"#0000FF", // 蓝
"#800080", // 紫
"#000000", // 黑
],
selectedThemeColor: "#000000", // 默认黑色
useCommonMainColor: false,
useCommonBgColor: false,
showSidebar: true,
expandSidebar: false,
changeModuleExpand: true,
changeUserCard: false,
enablePageRole: false,
enablePagePermission: false,
};
},
methods: {
selectStyle(style) {
this.selectedStyle = style;
this.$message.success(`已选择风格:${style}`);
},
selectLayout(layout) {
this.selectedLayout = layout;
this.$message.success(`已选择布局:${layout}`);
},
selectThemeColor(color) {
this.selectedThemeColor = color;
this.$message.success(`已选择主题色:${color}`);
},
resetTheme() {
this.selectedThemeColor = "#000000";
this.$message.success("已恢复默认主题(黑灰)");
},
saveSettings() {
const settings = {
style: this.selectedStyle,
layout: this.selectedLayout,
themeColor: this.selectedThemeColor,
useCommonMainColor: this.useCommonMainColor,
useCommonBgColor: this.useCommonBgColor,
showSidebar: this.showSidebar,
expandSidebar: this.expandSidebar,
changeModuleExpand: this.changeModuleExpand,
changeUserCard: this.changeUserCard,
enablePageRole: this.enablePageRole,
enablePagePermission: this.enablePagePermission,
};
console.log("保存设置:", settings);
this.$message.success("设置已保存,请重新登录以生效");
},
resetSettings() {
this.selectedStyle = "style3";
this.selectedLayout = "layout1";
this.selectedThemeColor = "#000000";
this.useCommonMainColor = false;
this.useCommonBgColor = false;
this.showSidebar = true;
this.expandSidebar = false;
this.changeModuleExpand = true;
this.changeUserCard = false;
this.enablePageRole = false;
this.enablePagePermission = false;
this.$message.success("已重置所有设置");
},
},
};
</script>
<style lang="less" scoped>
.theme-settings {
padding: 20px;
.nav-bar {
margin-bottom: 20px;
}
.settings-section {
background: #fff;
padding: 20px;
border-radius: 4px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
h3 {
margin-bottom: 20px;
font-size: 18px;
display: flex;
justify-content: space-between;
align-items: center;
}
.setting-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.label {
font-size: 14px;
color: #333;
}
.style-options,
.layout-options {
display: flex;
gap: 10px;
.style-block,
.layout-block {
width: 60px;
height: 40px;
border-radius: 4px;
border: 2px solid transparent;
cursor: pointer;
position: relative;
transition: border 0.3s;
&.selected {
border: 2px solid #409eff;
&:after {
content: "\2713"; /* 勾号 */
position: absolute;
top: 2px;
right: 2px;
color: #409eff;
font-size: 16px;
font-weight: bold;
}
}
.style-icon,
.layout-icon {
width: 100%;
height: 100%;
border-radius: 2px;
position: relative;
overflow: hidden;
}
/* 头部颜色条 */
.header-bar {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 8px; /* 头部高度 */
}
.header-dark {
background-color: #2c3e50; /* 深色头部 */
}
.header-light {
background-color: #ecf0f1; /* 浅色头部 */
}
/* 整体风格设置图标样式 */
.style1 {
background: linear-gradient(to right, #2c3e50 20%, #ecf0f1 20%);
}
.style2 {
background: linear-gradient(to right, #ecf0f1 20%, #ecf0f1 20%);
}
.style3 {
background: linear-gradient(to right, #2c3e50 20%, #2c3e50 20%);
}
/* 整体界面布局图标样式 */
.layout1 {
background: linear-gradient(to right, #2c3e50 20%, #ecf0f1 20%);
}
.layout2 {
background: linear-gradient(to right, #2c3e50 20%, #ecf0f1 20%);
}
.layout3 {
background: linear-gradient(to right, #2c3e50 20%, #2c3e50 20%);
}
}
}
.color-picker {
display: flex;
gap: 10px;
.color-block {
width: 30px;
height: 30px;
border-radius: 4px;
cursor: pointer;
border: 2px solid transparent;
transition: border 0.3s;
&.selected {
border: 2px solid #409eff;
}
}
}
}
.tip {
margin-bottom: 20px;
}
.actions {
text-align: right;
.el-button {
margin-left: 10px;
}
}
}
}
</style>