转为使用element-plus

This commit is contained in:
2026-01-25 14:09:47 +08:00
parent 5569e73ef1
commit 1134ecb732
73 changed files with 3 additions and 18855 deletions

View File

@@ -1,350 +0,0 @@
<template>
<a-drawer v-model:open="open" title="布局配置" placement="right" :width="420">
<div class="setting-content">
<div class="setting-item">
<div class="setting-title">布局模式</div>
<div class="layout-mode-list">
<div v-for="mode in layoutModes" :key="mode.value" class="layout-mode-item"
:class="{ active: layoutStore.layoutMode === mode.value }"
@click="handleLayoutChange(mode.value)">
<div class="layout-preview" :class="`preview-${mode.value}`">
<div class="preview-sidebar"></div>
<div v-if="mode.value === 'default'" class="preview-sidebar-2"></div>
<div class="preview-content">
<div class="preview-header"></div>
<div class="preview-body"></div>
</div>
</div>
<div class="layout-name">{{ mode.label }}</div>
<CheckOutlined v-if="layoutStore.layoutMode === mode.value" class="check-icon" />
</div>
</div>
</div>
<div class="setting-item">
<div class="setting-title">主题颜色</div>
<div class="color-list">
<div v-for="color in themeColors" :key="color" class="color-item"
:class="{ active: themeColor === color }" :style="{ backgroundColor: color }"
@click="changeThemeColor(color)">
<CheckOutlined v-if="themeColor === color" />
</div>
</div>
</div>
<div class="setting-item">
<div class="setting-title">显示设置</div>
<div class="toggle-list">
<div class="toggle-item">
<span>显示标签栏</span>
<a-switch v-model:checked="showTags" @change="handleShowTagsChange" />
</div>
<div class="toggle-item">
<span>显示面包屑</span>
<a-switch v-model:checked="showBreadcrumb" @change="handleShowBreadcrumbChange" />
</div>
</div>
</div>
<div class="setting-item">
<div class="setting-title">其他设置</div>
<div class="action-buttons">
<a-button type="primary" block @click="handleResetSettings">
<ReloadOutlined />
重置设置
</a-button>
</div>
</div>
</div>
</a-drawer>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { useLayoutStore } from '@/stores/modules/layout'
import { CheckOutlined, ReloadOutlined } from '@ant-design/icons-vue'
// 定义组件名称(多词命名)
defineOptions({
name: 'LayoutSetting',
})
const layoutStore = useLayoutStore()
const open = ref(false)
const themeColor = ref('#1890ff')
const showTags = ref(true)
const showBreadcrumb = ref(true)
const layoutModes = [
{ value: 'default', label: '默认布局' },
{ value: 'menu', label: '菜单布局' },
{ value: 'top', label: '顶部布局' },
]
const themeColors = ['#1890ff', '#f5222d', '#fa541c', '#faad14', '#13c2c2', '#52c41a', '#2f54eb', '#722ed1']
const openDrawer = () => {
open.value = true
}
const closeDrawer = () => {
open.value = false
}
defineExpose({
openDrawer,
closeDrawer,
})
// 切换布局
const handleLayoutChange = (mode) => {
layoutStore.setLayoutMode(mode)
const modeLabel = layoutModes.find((m) => m.value === mode)?.label || mode
message.success(`已切换到${modeLabel}`)
}
// 切换主题颜色
const changeThemeColor = (color) => {
themeColor.value = color
// 更新 CSS 变量
document.documentElement.style.setProperty('--primary-color', color)
message.success('主题颜色已更新')
}
// 切换标签栏显示
const handleShowTagsChange = (checked) => {
showTags.value = checked
// 触发自定义事件或更新状态
document.documentElement.style.setProperty('--show-tags', checked ? 'block' : 'none')
message.success(checked ? '标签栏已显示' : '标签栏已隐藏')
}
// 切换面包屑显示
const handleShowBreadcrumbChange = (checked) => {
showBreadcrumb.value = checked
message.success(checked ? '面包屑已显示' : '面包屑已隐藏')
}
// 重置设置
const handleResetSettings = () => {
themeColor.value = '#1890ff'
showTags.value = true
showBreadcrumb.value = true
layoutStore.setLayoutMode('default')
document.documentElement.style.setProperty('--primary-color', '#1890ff')
document.documentElement.style.setProperty('--show-tags', 'block')
message.success('设置已重置')
}
// 初始化
onMounted(() => {
// 从本地存储或其他地方恢复设置
const savedThemeColor = localStorage.getItem('themeColor')
if (savedThemeColor) {
themeColor.value = savedThemeColor
document.documentElement.style.setProperty('--primary-color', savedThemeColor)
}
const savedShowTags = localStorage.getItem('showTags')
if (savedShowTags !== null) {
showTags.value = savedShowTags === 'true'
document.documentElement.style.setProperty('--show-tags', savedShowTags === 'true' ? 'block' : 'none')
}
})
// 监听设置变化并保存到本地存储
watch(themeColor, (newVal) => {
localStorage.setItem('themeColor', newVal)
})
watch(showTags, (newVal) => {
localStorage.setItem('showTags', String(newVal))
})
</script>
<style scoped lang="scss">
.setting-content {
.setting-item {
margin-bottom: 32px;
.setting-title {
font-size: 14px;
font-weight: 500;
margin-bottom: 16px;
color: #333;
}
.layout-mode-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
.layout-mode-item {
position: relative;
border: 2px solid #e8e8e8;
border-radius: 8px;
padding: 12px;
cursor: pointer;
transition: all 0.3s;
&:hover {
border-color: var(--primary-color, #1890ff);
transform: translateY(-2px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
&.active {
border-color: var(--primary-color, #1890ff);
background-color: rgba(24, 144, 255, 0.05);
}
.layout-preview {
width: 100%;
height: 60px;
border-radius: 4px;
margin-bottom: 8px;
overflow: hidden;
display: flex;
background-color: #f0f2f5;
.preview-sidebar {
background-color: #001529;
}
.preview-sidebar-2 {
background-color: #fff;
border-left: 1px solid #e8e8e8;
}
.preview-content {
flex: 1;
padding: 4px;
.preview-header {
height: 8px;
background-color: #fff;
margin-bottom: 4px;
}
.preview-body {
height: calc(100% - 12px);
background-color: #e8e8e8;
}
}
&.preview-default {
.preview-sidebar {
width: 20px;
}
.preview-sidebar-2 {
width: 24px;
}
}
&.preview-menu {
.preview-sidebar {
width: 30px;
background-color: #fff;
border-right: 1px solid #e8e8e8;
}
}
&.preview-top {
flex-direction: column;
.preview-sidebar {
width: 100%;
height: 12px;
background-color: #fff;
}
.preview-content {
.preview-header {
display: none;
}
.preview-body {
height: 100%;
}
}
}
}
.layout-name {
font-size: 12px;
color: #666;
text-align: center;
}
.check-icon {
position: absolute;
top: 4px;
right: 4px;
color: var(--primary-color, #1890ff);
font-size: 12px;
}
}
}
.color-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
.color-item {
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
border: 2px solid transparent;
&:hover {
transform: scale(1.1);
}
&.active {
border-color: #fff;
box-shadow: 0 0 0 2px var(--primary-color, #1890ff);
.anticon {
color: #fff;
}
}
}
}
.toggle-list {
.toggle-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
span {
font-size: 14px;
color: #333;
}
}
}
.action-buttons {
:deep(.ant-btn) {
height: 40px;
font-size: 14px;
}
}
}
}
</style>