样式优化
This commit is contained in:
19
src/App.vue
19
src/App.vue
@@ -12,11 +12,11 @@ const listData: ListItem[] = Array.from({ length: 1000 }, (_, i) => ({
|
|||||||
// 随机选择一个图标
|
// 随机选择一个图标
|
||||||
icon: samplePic,
|
icon: samplePic,
|
||||||
tags: [
|
tags: [
|
||||||
{ id: 1, name: 'Vue', color: '#42b883' },
|
...(i % 2 === 0 ? [{ id: 1, name: 'Vue', color: '#42b883' }] : []),
|
||||||
{ id: 2, name: 'TypeScript', color: '#3178c6' },
|
...(i % 3 === 0 ? [{ id: 2, name: 'TypeScript', color: '#3178c6' }] : []),
|
||||||
...(i % 3 === 0 ? [{ id: 3, name: 'React', color: '#149eca' }] : []),
|
...(i % 4 === 0 ? [{ id: 3, name: 'React', color: '#149eca' }] : []),
|
||||||
...(i % 4 === 0 ? [{ id: 4, name: 'Node.js', color: '#539e43' }] : []),
|
...(i % 5 === 0 ? [{ id: 4, name: 'Node.js', color: '#539e43' }] : []),
|
||||||
]
|
],
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// 自定义菜单项
|
// 自定义菜单项
|
||||||
@@ -26,21 +26,21 @@ const menuItems: MenuItem[] = [
|
|||||||
label: '刷新列表',
|
label: '刷新列表',
|
||||||
action: (item) => {
|
action: (item) => {
|
||||||
console.log('当前选中项:', item)
|
console.log('当前选中项:', item)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'clear',
|
id: 'clear',
|
||||||
label: '清空选择',
|
label: '清空选择',
|
||||||
action: (item) => {
|
action: (item) => {
|
||||||
console.log('清空前选中项:', item)
|
console.log('清空前选中项:', item)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'export',
|
id: 'export',
|
||||||
label: '导出数据',
|
label: '导出数据',
|
||||||
action: (item) => {
|
action: (item) => {
|
||||||
console.log('当前选中项:', item)
|
console.log('当前选中项:', item)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -59,7 +59,8 @@ const handleItemClick = (item: ListItem): void => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -265,8 +265,34 @@ const onAfterLeave = (el: Element): void => {
|
|||||||
>
|
>
|
||||||
<div v-if="showMenu" class="popup-menu" @click.stop>
|
<div v-if="showMenu" class="popup-menu" @click.stop>
|
||||||
<div v-if="selectedItem" class="selected-item-info">
|
<div v-if="selectedItem" class="selected-item-info">
|
||||||
|
<div class="selected-item-header">
|
||||||
|
<div class="selected-item-icon">
|
||||||
|
<img
|
||||||
|
v-if="selectedItem.icon"
|
||||||
|
:src="selectedItem.icon"
|
||||||
|
:alt="selectedItem.name"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
>
|
||||||
|
<svg v-else viewBox="0 0 24 24" width="16" height="16">
|
||||||
|
<circle cx="12" cy="12" r="10" fill="rgba(0, 0, 0, 0.38)" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
<div class="selected-item-name">{{ selectedItem.name }}</div>
|
<div class="selected-item-name">{{ selectedItem.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="selected-item-content">
|
||||||
<div class="selected-item-path">{{ selectedItem.path }}</div>
|
<div class="selected-item-path">{{ selectedItem.path }}</div>
|
||||||
|
<div class="selected-item-tags" v-if="selectedItem.tags?.length">
|
||||||
|
<span
|
||||||
|
v-for="tag in selectedItem.tags"
|
||||||
|
:key="tag.id"
|
||||||
|
class="selected-item-tag"
|
||||||
|
:style="{ backgroundColor: tag.color }"
|
||||||
|
>
|
||||||
|
{{ tag.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-divider"></div>
|
<div class="menu-divider"></div>
|
||||||
<div
|
<div
|
||||||
@@ -367,7 +393,7 @@ const onAfterLeave = (el: Element): void => {
|
|||||||
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
||||||
0 8px 10px 1px rgba(0, 0, 0, 0.14),
|
0 8px 10px 1px rgba(0, 0, 0, 0.14),
|
||||||
0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
min-width: 260px;
|
min-width: 320px;
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
transform-origin: top right;
|
transform-origin: top right;
|
||||||
@@ -415,8 +441,8 @@ const onAfterLeave = (el: Element): void => {
|
|||||||
/* 菜单项悬停和选中状态 */
|
/* 菜单项悬停和选中状态 */
|
||||||
.menu-item:hover,
|
.menu-item:hover,
|
||||||
.menu-item-selected {
|
.menu-item-selected {
|
||||||
background-color: rgba(98, 0, 238, 0.08);
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
color: rgb(98, 0, 238);
|
color: rgba(0, 0, 0, 0.87);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 选中项信息区域 */
|
/* 选中项信息区域 */
|
||||||
@@ -426,12 +452,50 @@ const onAfterLeave = (el: Element): void => {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 选中项头部区域 */
|
||||||
|
.selected-item-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中项图标容器 */
|
||||||
|
.selected-item-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: rgba(0, 0, 0, 0.54);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中项图标图片 */
|
||||||
|
.selected-item-icon img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
/* 选中项名称 */
|
/* 选中项名称 */
|
||||||
.selected-item-name {
|
.selected-item-name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: rgba(0, 0, 0, 0.87);
|
color: rgba(0, 0, 0, 0.87);
|
||||||
margin-bottom: 8px;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中项内容区域 */
|
||||||
|
.selected-item-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 选中项路径 */
|
/* 选中项路径 */
|
||||||
@@ -442,6 +506,26 @@ const onAfterLeave = (el: Element): void => {
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 选中项标签容器 */
|
||||||
|
.selected-item-tags {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中项标签样式 */
|
||||||
|
.selected-item-tag {
|
||||||
|
font-size: 10px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
white-space: nowrap;
|
||||||
|
letter-spacing: 0.4px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #fff !important;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
/* Toast 消息容器:居中显示的浮动提示 */
|
/* Toast 消息容器:居中显示的浮动提示 */
|
||||||
.toast {
|
.toast {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ const lastReachBoundaryTime = ref<{ top: number; bottom: number }>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理键盘事件
|
* 处理<EFBFBD><EFBFBD>盘事件
|
||||||
* 实现键盘导航、边界循环和项目选择功能
|
* 实现键盘导航、边界循环和项目选择功能
|
||||||
* @param e 键盘事件对象
|
* @param e 键盘事件对象
|
||||||
*/
|
*/
|
||||||
@@ -466,7 +466,7 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
/* 选中状态样式 */
|
/* 选中状态样式 */
|
||||||
.list-item.selected {
|
.list-item.selected {
|
||||||
background-color: rgba(98, 0, 238, 0.08);
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 列表项布局容器 */
|
/* 列表项布局容器 */
|
||||||
|
|||||||
Reference in New Issue
Block a user