更新:课程首页增加骨架屏
This commit is contained in:
139
pages/index.vue
Normal file
139
pages/index.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="menu-container">
|
||||
|
||||
<!-- 一级导航 -->
|
||||
<div class="menu-level-1">
|
||||
<div
|
||||
v-for="item in level1"
|
||||
:key="item.id"
|
||||
class="menu-item"
|
||||
:class="{ active: selectedParentId === item.id }"
|
||||
@click="selectParent(item)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 二级导航区域 -->
|
||||
<transition name="fade">
|
||||
<div
|
||||
v-if="childList.length"
|
||||
class="menu-level-2"
|
||||
:style="{ gridRowStart: childRowIndex }"
|
||||
>
|
||||
<div
|
||||
v-for="child in childList"
|
||||
:key="child.id"
|
||||
class="menu-item child"
|
||||
>
|
||||
{{ child.name }}
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from "vue"
|
||||
|
||||
// 模拟接口返回的一级导航
|
||||
const level1 = ref([
|
||||
{ id: 1, name: "导航1", children: [] },
|
||||
{ id: 2, name: "导航2", children: [
|
||||
{ id: 21, name: "子2-1" },
|
||||
{ id: 22, name: "子2-2" },
|
||||
{ id: 23, name: "子2-3" }
|
||||
]},
|
||||
{ id: 3, name: "导航3", children: [] },
|
||||
{ id: 4, name: "导航4", children: [
|
||||
{ id: 41, name: "子4-1" },
|
||||
{ id: 42, name: "子4-2" }
|
||||
]},
|
||||
{ id: 5, name: "导航5", children: [] },
|
||||
{ id: 6, name: "导航6", children: [
|
||||
{ id: 61, name: "子6-1" },
|
||||
{ id: 62, name: "子6-2" },
|
||||
{ id: 63, name: "子6-3" },
|
||||
{ id: 64, name: "子6-4" },
|
||||
]},
|
||||
{ id: 7, name: "导航7", children: [] },
|
||||
{ id: 8, name: "导航8", children: [] }
|
||||
])
|
||||
|
||||
// 选择的一级导航
|
||||
const selectedParentId = ref(null)
|
||||
|
||||
// 当前一级导航的子级
|
||||
const childList = computed(() => {
|
||||
const parent = level1.value.find(i => i.id === selectedParentId.value)
|
||||
return parent ? parent.children : []
|
||||
})
|
||||
|
||||
// 计算二级导航应该显示在哪一行(每行 4 个)
|
||||
const childRowIndex = computed(() => {
|
||||
if (!selectedParentId.value) return 3
|
||||
const index = level1.value.findIndex(i => i.id === selectedParentId.value)
|
||||
return Math.floor(index / 4) + 2 // 第一行 row=1,二级导航从 row=2 或 row=3
|
||||
})
|
||||
|
||||
const selectParent = (item) => {
|
||||
// 点击同一个时关闭
|
||||
if (selectedParentId.value === item.id) {
|
||||
selectedParentId.value = null
|
||||
} else {
|
||||
selectedParentId.value = item.id
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.menu-container {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto auto;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 一级导航:4列布局 */
|
||||
.menu-level-1 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
background: #4a90e2;
|
||||
color: white;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-item.active {
|
||||
background: #2d73c7;
|
||||
}
|
||||
|
||||
/* 二级导航:自动换行 */
|
||||
.menu-level-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
background: #2d73c7;
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.menu-item.child {
|
||||
background: #1e4f8a;
|
||||
}
|
||||
|
||||
/* 动画 */
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: all .2s ease;
|
||||
}
|
||||
.fade-enter-from, .fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user