Files
test-repo/docs/.vitepress/theme/components/appendix/web-basics/NetworkLayers.vue
T

369 lines
7.6 KiB
Vue
Raw Normal View History

2026-01-15 20:10:19 +08:00
<template>
<div class="network-layers">
<div class="layers-stack">
<div
v-for="(layer, index) in layers"
:key="layer.name"
class="layer-card"
:class="{ active: selectedLayer === index }"
@click="selectedLayer = index"
>
<div class="layer-number">
{{ index + 1 }}
</div>
2026-01-15 20:10:19 +08:00
<div class="layer-content">
<div class="layer-name">
{{ layer.name }}
</div>
<div class="layer-english">
{{ layer.english }}
</div>
<div class="layer-protocols">
{{ layer.protocols }}
</div>
</div>
<div class="layer-icon">
{{ layer.icon }}
2026-01-15 20:10:19 +08:00
</div>
</div>
</div>
<div
v-if="selectedLayer !== null"
class="layer-detail"
>
<div class="detail-title">
{{ layers[selectedLayer].name }}
</div>
<div class="detail-desc">
{{ layers[selectedLayer].description }}
</div>
2026-01-15 20:10:19 +08:00
<div class="detail-functions">
<div class="function-title">
主要功能
</div>
2026-01-15 20:10:19 +08:00
<div class="function-list">
<div
v-for="(func, index) in layers[selectedLayer].functions"
:key="index"
class="function-item"
>
2026-01-15 20:10:19 +08:00
{{ func }}
</div>
</div>
</div>
<div class="detail-examples">
<div class="example-title">
常见设备
</div>
2026-01-15 20:10:19 +08:00
<div class="example-list">
<div
v-for="(device, index) in layers[selectedLayer].devices"
:key="index"
class="example-item"
>
2026-01-15 20:10:19 +08:00
📡 {{ device }}
</div>
</div>
</div>
</div>
<div class="data-flow">
<div class="flow-title">
数据封装过程发送
</div>
2026-01-15 20:10:19 +08:00
<div class="flow-steps">
<div
v-for="(step, index) in 5"
:key="index"
class="flow-step"
>
<div class="step-label">
{{ layers[4 - index].name }}
</div>
2026-01-15 20:10:19 +08:00
<div class="step-box">
<span class="box-label">{{ layers[4 - index].dataUnit }}</span>
</div>
<div
v-if="index < 4"
class="step-arrow"
>
添加头部
</div>
2026-01-15 20:10:19 +08:00
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedLayer = ref(0)
const layers = [
{
name: '应用层',
english: 'Application Layer',
protocols: 'HTTP, HTTPS, FTP, SMTP, DNS, SSH',
icon: '📱',
dataUnit: '数据',
description:
'直接为用户的应用程序(如浏览器、邮件客户端)提供网络服务接口。',
2026-01-15 20:10:19 +08:00
functions: [
'为应用程序提供网络接口',
'定义应用程序间通信的协议',
'处理数据格式和加密',
'用户认证和授权'
],
devices: ['网关', '防火墙', '代理服务器']
},
{
name: '传输层',
english: 'Transport Layer',
protocols: 'TCP, UDP',
icon: '🚚',
dataUnit: '段/数据报',
description: '负责端到端的通信,确保数据可靠地从源端传输到目的端。',
functions: [
'分段和重组数据',
'端口号寻址(进程间通信)',
'流量控制和拥塞控制',
'错误检测和纠正(TCP'
],
devices: ['防火墙', '负载均衡器']
},
{
name: '网络层',
english: 'Network Layer',
protocols: 'IP, ICMP, IGMP, ARP',
icon: '🌐',
dataUnit: '包',
description: '负责数据包的路由选择,通过网络将数据从源主机传输到目的主机。',
functions: [
'逻辑寻址(IP 地址)',
'路由选择和转发',
'分组交换',
'拥塞控制'
],
devices: ['路由器', '三层交换机']
},
{
name: '数据链路层',
english: 'Data Link Layer',
protocols: 'Ethernet, Wi-Fi, PPP',
icon: '🔗',
dataUnit: '帧',
description: '负责在直连的两个节点间传输数据,处理物理层的错误。',
functions: [
'物理地址寻址(MAC 地址)',
'帧的封装和解封装',
'错误检测(CRC',
'流量控制',
'介质访问控制(MAC'
],
devices: ['交换机', '网桥', '网卡']
},
{
name: '物理层',
english: 'Physical Layer',
protocols: 'Ethernet PHY, Wi-Fi Radio, USB',
icon: '⚡',
dataUnit: '比特',
description: '负责在物理介质上传输原始的比特流(0 和 1)。',
functions: [
'定义物理设备标准',
'传输介质规范',
'比特传输和同步',
'电气特性和机械特性'
],
devices: ['中继器', '集线器', '网线', '光纤']
}
]
</script>
<style scoped>
.network-layers {
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
2026-01-15 20:10:19 +08:00
padding: 20px;
background: var(--vp-c-bg-soft);
margin: 20px 0;
}
.layers-stack {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 25px;
}
.layer-card {
display: flex;
align-items: center;
gap: 15px;
background: var(--vp-c-bg);
border: 2px solid var(--vp-c-divider);
border-radius: 6px;
2026-01-15 20:10:19 +08:00
padding: 15px;
cursor: pointer;
transition: all 0.3s;
}
.layer-card:hover {
border-color: var(--vp-c-brand);
transform: translateX(5px);
}
.layer-card.active {
border-color: var(--vp-c-brand);
background: var(--vp-c-bg-soft);
}
.layer-number {
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--vp-c-brand);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1.1rem;
}
.layer-content {
flex: 1;
}
.layer-name {
font-size: 1.1rem;
font-weight: bold;
color: var(--vp-c-text-1);
margin-bottom: 4px;
}
.layer-english {
font-size: 0.85rem;
color: var(--vp-c-text-3);
margin-bottom: 6px;
}
.layer-protocols {
font-size: 0.8rem;
color: var(--vp-c-brand);
font-family: monospace;
}
.layer-icon {
font-size: 2rem;
}
.layer-detail {
background: var(--vp-c-bg);
border-radius: 6px;
2026-01-15 20:10:19 +08:00
padding: 20px;
margin-bottom: 25px;
border-left: 4px solid var(--vp-c-brand);
}
.detail-title {
font-size: 1.2rem;
font-weight: bold;
color: var(--vp-c-text-1);
margin-bottom: 10px;
}
.detail-desc {
font-size: 0.95rem;
color: var(--vp-c-text-2);
line-height: 1.8;
margin-bottom: 20px;
}
.detail-functions,
.detail-examples {
margin-bottom: 15px;
}
.function-title,
.example-title {
font-size: 0.95rem;
font-weight: bold;
color: var(--vp-c-text-1);
margin-bottom: 10px;
}
.function-list,
.example-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.function-item,
.example-item {
font-size: 0.85rem;
color: var(--vp-c-text-2);
padding-left: 10px;
}
.data-flow {
background: var(--vp-c-bg);
border-radius: 6px;
2026-01-15 20:10:19 +08:00
padding: 20px;
}
.flow-title {
font-size: 1rem;
font-weight: bold;
color: var(--vp-c-text-1);
margin-bottom: 15px;
text-align: center;
}
.flow-steps {
display: flex;
flex-direction: column;
gap: 10px;
}
.flow-step {
display: flex;
align-items: center;
gap: 15px;
}
.step-label {
width: 100px;
font-size: 0.85rem;
font-weight: 600;
color: var(--vp-c-text-2);
text-align: right;
}
.step-box {
flex: 1;
background: var(--vp-c-bg-soft);
border: 2px solid var(--vp-c-brand);
border-radius: 6px;
padding: 10px;
text-align: center;
position: relative;
}
.box-label {
font-size: 0.85rem;
color: var(--vp-c-brand);
font-weight: 600;
}
.step-arrow {
width: 100px;
font-size: 0.75rem;
color: var(--vp-c-text-3);
text-align: center;
}
</style>