refactor: ♻️ 布局选择组件代码优化

This commit is contained in:
ray
2025-02-18 13:23:44 +08:00
parent 583bdd631b
commit a1b4efe9d7

View File

@@ -1,35 +1,20 @@
<template> <template>
<div class="flex flex-wrap justify-around w-full h-12"> <div class="layout-select">
<el-tooltip content="左侧模式" placement="bottom"> <el-tooltip
v-for="item in layoutOptions"
:key="item.value"
:content="item.label"
placement="bottom"
>
<div <div
class="layout-item left" role="button"
:class="{ 'is-active': modelValue === LayoutEnum.LEFT }" tabindex="0"
@click="handleLayoutChange(LayoutEnum.LEFT)" :class="['layout-item', item.className, { 'is-active': modelValue === item.value }]"
@click="handleLayoutChange(item.value)"
@keydown.enter.space="handleLayoutChange(item.value)"
> >
<div /> <div class="layout-item-part" />
<div /> <div class="layout-item-part" />
</div>
</el-tooltip>
<el-tooltip content="顶部模式" placement="bottom">
<div
class="layout-item top"
:class="{ 'is-active': modelValue === LayoutEnum.TOP }"
@click="handleLayoutChange(LayoutEnum.TOP)"
>
<div />
<div />
</div>
</el-tooltip>
<el-tooltip content="混合模式" placement="bottom">
<div
class="layout-item mix"
:class="{ 'is-active': modelValue === LayoutEnum.MIX }"
@click="handleLayoutChange(LayoutEnum.MIX)"
>
<div />
<div />
</div> </div>
</el-tooltip> </el-tooltip>
</div> </div>
@@ -38,76 +23,118 @@
<script lang="ts" setup> <script lang="ts" setup>
import { LayoutEnum } from "@/enums/LayoutEnum"; import { LayoutEnum } from "@/enums/LayoutEnum";
const modelValue = defineModel("modelValue", { interface LayoutOption {
type: String, value: LayoutEnum;
label: string;
className: string;
}
const layoutOptions: LayoutOption[] = [
{ value: LayoutEnum.LEFT, label: "左侧模式", className: "left" },
{ value: LayoutEnum.TOP, label: "顶部模式", className: "top" },
{ value: LayoutEnum.MIX, label: "混合模式", className: "mix" },
];
const modelValue = defineModel<LayoutEnum>("modelValue", {
required: true, required: true,
default: () => "", default: () => LayoutEnum.LEFT,
}); });
/** function handleLayoutChange(layout: LayoutEnum) {
* 变换布局
*
* @param layout
*/
function handleLayoutChange(layout: string) {
modelValue.value = layout; modelValue.value = layout;
} }
</script> </script>
<style scoped> <style scoped lang="scss">
.layout-selector { .layout-select {
display: flex; display: flex;
flex-wrap: wrap; gap: 10px;
justify-content: space-around; justify-content: space-evenly;
width: 100%; padding: 10px 0;
height: 50px; --layout-primary: #1b2a47;
--layout-background: #f0f2f5;
--layout-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
--layout-hover: #e3f1f9;
} }
.layout-item { .layout-item {
position: relative; position: relative;
width: 18%; width: 18%;
height: 45px; height: 50px;
overflow: hidden;
cursor: pointer; cursor: pointer;
background: #f0f2f5; background: var(--layout-background);
border-radius: 4px; border-radius: 8px;
box-shadow: var(--layout-shadow);
&.mix div:nth-child(1), transition:
&.top div:nth-child(1) { transform 0.2s ease,
width: 100%; border-color 0.2s ease,
height: 30%; box-shadow 0.2s ease;
background: #1b2a47;
box-shadow: 0 0 1px #888; &:hover {
background-color: var(--layout-hover);
transform: scale(1.02); /* 稍微放大,避免过于夸张 */
} }
&.mix div:nth-child(2) { &:focus-visible {
outline: 2px solid var(--el-color-primary);
}
&-part {
position: absolute; position: absolute;
bottom: 0; background: var(--layout-primary);
left: 0; border-radius: 4px; /* 保持和父容器一致的圆角 */
width: 30%; box-shadow: var(--layout-shadow);
height: 70%; transition: all 0.3s ease;
background: #1b2a47;
box-shadow: 0 0 1px #888;
} }
&.left div:nth-child(1) { &.left {
width: 30%; .layout-item-part {
height: 100%; &:first-child {
background: #1b2a47; width: 30%;
height: 100%;
border-radius: 4px 0 0 4px; /* 左边部分圆角 */
}
&:last-child {
top: 0;
right: 0;
width: 70%;
height: 30%;
background: #fff;
border-radius: 0 4px 4px 0; /* 右边部分圆角 */
}
}
} }
&.left div:nth-child(2) { &.top {
position: absolute; .layout-item-part:first-child {
top: 0; width: 100%;
right: 0; height: 30%;
width: 70%; border-radius: 4px 4px 0 0; /* 顶部部分圆角 */
height: 30%; }
background: #fff; }
box-shadow: 0 0 1px #888;
&.mix {
.layout-item-part {
&:first-child {
width: 100%;
height: 30%;
border-radius: 4px 4px 0 0; /* 顶部部分圆角 */
}
&:last-child {
bottom: 0;
left: 0;
width: 30%;
height: 70%;
border-radius: 0 0 4px 4px; /* 底部部分圆角 */
}
}
} }
} }
.layout-item.is-active { .is-active {
background-color: var(--layout-hover);
border: 2px solid var(--el-color-primary); border: 2px solid var(--el-color-primary);
transform: scale(1.05); /* 轻微放大 */
} }
</style> </style>