更新
This commit is contained in:
@@ -1,141 +1,51 @@
|
||||
<template>
|
||||
<div class="setting-container">
|
||||
<!-- 设置按钮 -->
|
||||
<div class="setting-btn" @click="showDrawer = true">
|
||||
<el-icon>
|
||||
<Setting />
|
||||
<div class="drawer-container">
|
||||
<el-drawer v-model="drawerVisible" title="布局设置" size="280px">
|
||||
<el-scrollbar>
|
||||
<el-form label-width="100px" label-position="left">
|
||||
<el-form-item label="布局模式">
|
||||
<el-select v-model="layoutMode" placeholder="请选择" @change="handleLayoutModeChange">
|
||||
<el-option label="默认布局" value="default" />
|
||||
<el-option label="菜单布局" value="menu" />
|
||||
<el-option label="顶部布局" value="top" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="主题颜色">
|
||||
<el-color-picker v-model="themeColor" @change="handleThemeChange" />
|
||||
</el-form-item>
|
||||
|
||||
<el-divider>显示设置</el-divider>
|
||||
|
||||
<el-form-item label="显示标签栏">
|
||||
<el-switch v-model="showTags" @change="handleShowTagsChange" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="显示面包屑">
|
||||
<el-switch v-model="showBreadcrumb" @change="handleShowBreadcrumbChange" />
|
||||
</el-form-item>
|
||||
|
||||
<el-divider>其他</el-divider>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleReset">重置设置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
</el-drawer>
|
||||
|
||||
<div class="setting-btn" @click="drawerVisible = true">
|
||||
<el-icon :size="24">
|
||||
<component :is="'ElIconSetting'" />
|
||||
</el-icon>
|
||||
</div>
|
||||
|
||||
<!-- 设置抽屉 -->
|
||||
<el-drawer v-model="showDrawer" title="系统设置" :size="300" :close-on-click-modal="false">
|
||||
<div class="setting-content">
|
||||
<!-- 布局模式 -->
|
||||
<div class="setting-item">
|
||||
<div class="setting-title">布局模式</div>
|
||||
<div class="setting-value">
|
||||
<el-radio-group v-model="layoutMode" @change="handleLayoutModeChange">
|
||||
<el-radio label="default">
|
||||
<div class="layout-option">
|
||||
<div class="layout-preview layout-default">
|
||||
<div class="layout-aside-left"></div>
|
||||
<div class="layout-aside-right"></div>
|
||||
<div class="layout-main"></div>
|
||||
</div>
|
||||
<span>双栏布局</span>
|
||||
</div>
|
||||
</el-radio>
|
||||
<el-radio label="menu">
|
||||
<div class="layout-option">
|
||||
<div class="layout-preview layout-menu">
|
||||
<div class="layout-aside"></div>
|
||||
<div class="layout-main"></div>
|
||||
</div>
|
||||
<span>菜单布局</span>
|
||||
</div>
|
||||
</el-radio>
|
||||
<el-radio label="top">
|
||||
<div class="layout-option">
|
||||
<div class="layout-preview layout-top">
|
||||
<div class="layout-header"></div>
|
||||
<div class="layout-main"></div>
|
||||
</div>
|
||||
<span>顶部布局</span>
|
||||
</div>
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主题色 -->
|
||||
<div class="setting-item">
|
||||
<div class="setting-title">主题色</div>
|
||||
<div class="setting-value">
|
||||
<div class="color-picker-wrapper">
|
||||
<el-color-picker v-model="themeColor" show-alpha :predefine="predefineColors" @change="handleThemeColorChange" />
|
||||
</div>
|
||||
<div class="color-presets">
|
||||
<div v-for="color in predefineColors" :key="color" class="color-preset" :class="{ active: themeColor === color }" :style="{ backgroundColor: color }" @click="handleColorPresetClick(color)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主题模式 -->
|
||||
<div class="setting-item">
|
||||
<div class="setting-title">主题模式</div>
|
||||
<div class="setting-value">
|
||||
<el-radio-group v-model="isDark" @change="handleThemeModeChange">
|
||||
<el-radio :label="false">
|
||||
<el-icon>
|
||||
<Sunny />
|
||||
</el-icon>
|
||||
浅色
|
||||
</el-radio>
|
||||
<el-radio :label="true">
|
||||
<el-icon>
|
||||
<Moon />
|
||||
</el-icon>
|
||||
深色
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 标签栏 -->
|
||||
<div class="setting-item">
|
||||
<div class="setting-title">
|
||||
<span>显示标签栏</span>
|
||||
<el-tooltip content="开启后页面顶部显示标签页" placement="top">
|
||||
<el-icon>
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
<el-switch v-model="showTags" @change="handleShowTagsChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 面包屑 -->
|
||||
<div class="setting-item">
|
||||
<div class="setting-title">
|
||||
<span>显示面包屑</span>
|
||||
<el-tooltip content="开启后页面顶部显示面包屑导航" placement="top">
|
||||
<el-icon>
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
<el-switch v-model="showBreadcrumb" @change="handleShowBreadcrumbChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="setting-actions">
|
||||
<el-button type="primary" @click="handleSave">
|
||||
<el-icon>
|
||||
<Check />
|
||||
</el-icon>
|
||||
保存配置
|
||||
</el-button>
|
||||
<el-button @click="handleReset">
|
||||
<el-icon>
|
||||
<RefreshLeft />
|
||||
</el-icon>
|
||||
重置默认
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import { useLayoutStore } from '../../stores/modules/layout'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Setting, Sunny, Moon, QuestionFilled, Check, RefreshLeft } from '@element-plus/icons-vue'
|
||||
import { useLayoutStore } from '@/stores/modules/layout'
|
||||
|
||||
defineOptions({
|
||||
name: 'LayoutSetting',
|
||||
@@ -143,350 +53,94 @@ defineOptions({
|
||||
|
||||
const layoutStore = useLayoutStore()
|
||||
|
||||
// 抽屉显示状态
|
||||
const showDrawer = ref(false)
|
||||
|
||||
// 预定义颜色
|
||||
const predefineColors = [
|
||||
'#1890ff',
|
||||
'#409eff',
|
||||
'#67c23a',
|
||||
'#e6a23c',
|
||||
'#f56c6c',
|
||||
'#909399',
|
||||
'#722ed1',
|
||||
'#eb2f96',
|
||||
'#52c41a',
|
||||
'#1890ff',
|
||||
'#2f54eb',
|
||||
'#722ed1',
|
||||
'#f5222d',
|
||||
'#fa541c',
|
||||
'#fa8c16',
|
||||
'#faad14',
|
||||
'#fadb14',
|
||||
'#a0d911',
|
||||
'#52c41a',
|
||||
'#13c2c2',
|
||||
'#1890ff',
|
||||
'#2f54eb',
|
||||
'#722ed1',
|
||||
]
|
||||
const drawerVisible = ref(false)
|
||||
|
||||
// 布局模式
|
||||
const layoutMode = computed({
|
||||
get: () => layoutStore.layoutMode,
|
||||
set: (val) => layoutStore.setLayoutMode(val),
|
||||
set: (value) => {
|
||||
layoutStore.setLayoutMode(value)
|
||||
},
|
||||
})
|
||||
|
||||
// 主题色
|
||||
const themeColor = ref(layoutStore.themeColor)
|
||||
|
||||
// 主题模式(深色/浅色)
|
||||
const isDark = ref(document.documentElement.classList.contains('dark'))
|
||||
// 主题颜色
|
||||
const themeColor = computed({
|
||||
get: () => layoutStore.themeColor,
|
||||
set: (value) => {
|
||||
layoutStore.setThemeColor(value)
|
||||
},
|
||||
})
|
||||
|
||||
// 显示标签栏
|
||||
const showTags = computed({
|
||||
get: () => layoutStore.showTags,
|
||||
set: (val) => layoutStore.setShowTags(val),
|
||||
set: (value) => {
|
||||
layoutStore.setShowTags(value)
|
||||
},
|
||||
})
|
||||
|
||||
// 显示面包屑
|
||||
const showBreadcrumb = computed({
|
||||
get: () => layoutStore.showBreadcrumb,
|
||||
set: (val) => layoutStore.setShowBreadcrumb(val),
|
||||
set: (value) => {
|
||||
layoutStore.setShowBreadcrumb(value)
|
||||
},
|
||||
})
|
||||
|
||||
// 布局模式变化
|
||||
const handleLayoutModeChange = (value) => {
|
||||
console.log('Layout mode changed:', value)
|
||||
layoutStore.setLayoutMode(value)
|
||||
ElMessage.success('布局模式已切换')
|
||||
}
|
||||
|
||||
// 主题色变化
|
||||
const handleThemeColorChange = (value) => {
|
||||
if (value) {
|
||||
layoutStore.setThemeColor(value)
|
||||
}
|
||||
// 主题颜色变化
|
||||
const handleThemeChange = (value) => {
|
||||
layoutStore.setThemeColor(value)
|
||||
}
|
||||
|
||||
// 预定义颜色点击
|
||||
const handleColorPresetClick = (color) => {
|
||||
themeColor.value = color
|
||||
layoutStore.setThemeColor(color)
|
||||
}
|
||||
|
||||
// 主题模式变化
|
||||
const handleThemeModeChange = (value) => {
|
||||
if (value) {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
}
|
||||
|
||||
// 标签栏显示变化
|
||||
// 显示标签栏变化
|
||||
const handleShowTagsChange = (value) => {
|
||||
layoutStore.setShowTags(value)
|
||||
}
|
||||
|
||||
// 面包屑显示变化
|
||||
// 显示面包屑变化
|
||||
const handleShowBreadcrumbChange = (value) => {
|
||||
layoutStore.setShowBreadcrumb(value)
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
const handleSave = () => {
|
||||
ElMessage.success('配置已保存')
|
||||
showDrawer.value = false
|
||||
}
|
||||
|
||||
// 重置配置
|
||||
// 重置设置
|
||||
const handleReset = () => {
|
||||
layoutStore.resetTheme()
|
||||
themeColor.value = layoutStore.themeColor
|
||||
isDark.value = false
|
||||
document.documentElement.classList.remove('dark')
|
||||
ElMessage.success('已重置为默认配置')
|
||||
ElMessage.success('设置已重置')
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
themeColor.value = layoutStore.themeColor
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.setting-container {
|
||||
// 设置按钮
|
||||
.drawer-container {
|
||||
.setting-btn {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translateY(-50%);
|
||||
z-index: 9999;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--el-color-primary);
|
||||
background: var(--primary-color);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: 6px 0 0 6px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
z-index: 9999;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: var(--primary-color);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 20px;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
width: 56px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
|
||||
.el-icon {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(-50%) scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置内容
|
||||
.setting-content {
|
||||
padding: 20px;
|
||||
|
||||
.setting-item {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.setting-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-primary);
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
.el-icon {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-secondary);
|
||||
cursor: help;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-value {
|
||||
// 布局选项
|
||||
:deep(.el-radio-group) {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
.el-radio {
|
||||
margin-right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-radio__label {
|
||||
width: 100%;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
border: 2px solid var(--el-border-color);
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
background-color: var(--el-fill-color-light);
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
// 布局预览
|
||||
.layout-preview {
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
background: var(--el-fill-color-blank);
|
||||
border: 2px solid var(--el-border-color);
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&.layout-default {
|
||||
.layout-aside-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 20px;
|
||||
background: var(--el-color-primary-light-7);
|
||||
}
|
||||
|
||||
.layout-aside-right {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 25px;
|
||||
background: var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
.layout-main {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 45px;
|
||||
background: var(--el-fill-color-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
&.layout-menu {
|
||||
.layout-aside {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 25px;
|
||||
background: var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
.layout-main {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 25px;
|
||||
background: var(--el-fill-color-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
&.layout-top {
|
||||
.layout-header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 12px;
|
||||
background: var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
.layout-main {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 12px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: var(--el-fill-color-lighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 颜色选择器
|
||||
.color-picker-wrapper {
|
||||
margin-bottom: 12px;
|
||||
|
||||
:deep(.el-color-picker__trigger) {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.color-presets {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 8px;
|
||||
|
||||
.color-preset {
|
||||
width: 100%;
|
||||
padding-bottom: 100%;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
border: 2px solid transparent;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: var(--el-color-primary);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.setting-actions {
|
||||
margin-top: 32px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid var(--el-border-color-light);
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
.el-button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user