Files
test-repo/docs/.vitepress/theme/components/appendix/computer-fundamentals/AppLaunchDemo.vue
T
sanbuphy df51f84ab5 docs: 重构 README 附录展示 & 新增多个附录交互组件
README 更新:
- 移除顶部 header.png 横幅图片
- 新增「附录知识库」板块,以 3×3 网格展示 9 大知识领域精选内容
- 附录链接指向部署版网站 (datawhalechina.github.io)
- 阶段表格新增「附录」行,突出 80+ 交互式专题
- 章节标题「新手入门 & PM」简化为「零基础入门」
- News 新增 2026-02-25 附录知识库更新条目

新增交互组件:
- 异步任务队列 (async-task-queues) 演示组件
- 文件存储 (file-storage) 演示组件
- 项目架构 (project-architecture) 演示组件
- 限流与背压 (rate-limiting) 演示组件
- 搜索引擎 (search-engines) 演示组件
- 计算机基础: AppLaunch/BiosUefi/OSBoot 等启动流程演示组件

新增附录文档:
- 前端项目架构 (frontend-project-architecture.md)
- 后端项目架构 (backend-project-architecture.md)

内容优化:
- 算法思维、数据结构、编程语言、调试艺术等多篇附录内容更新
- HTML/CSS 布局、请求旅程等前后端文档完善
- 附录索引页 (index.md) 同步更新
2026-02-25 12:22:49 +08:00

338 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="launch-demo">
<div class="demo-header">
<span class="demo-icon">🌐</span>
<span class="demo-title">浏览器启动过程</span>
<span class="demo-hint">点击每一步查看详情</span>
</div>
<div class="timeline">
<div
v-for="(step, i) in steps"
:key="i"
class="timeline-item"
:class="{ active: active === i, done: active > i }"
@click="active = active === i ? -1 : i"
>
<div class="marker-col">
<div class="dot">
<span v-if="active > i" class="check"></span>
<span v-else>{{ i + 1 }}</span>
</div>
<div v-if="i < steps.length - 1" class="line"></div>
</div>
<div class="card">
<div class="card-header">
<span class="step-icon">{{ step.icon }}</span>
<div class="card-titles">
<div class="step-name">{{ step.name }}</div>
<div class="step-brief">{{ step.brief }}</div>
</div>
<span class="expand-icon">{{ active === i ? '▾' : '▸' }}</span>
</div>
<transition name="slide">
<div v-if="active === i" class="card-detail">
<div class="detail-desc">{{ step.detail }}</div>
<div class="detail-visual">
<div
v-for="(item, j) in step.items"
:key="j"
class="visual-item"
>
<span class="vi-icon">{{ item.icon }}</span>
<div class="vi-text">
<span class="vi-label">{{ item.label }}</span>
<span class="vi-desc">{{ item.desc }}</span>
</div>
</div>
</div>
<div v-if="step.analogy" class="analogy">
<span class="analogy-icon">💡</span>
<span class="analogy-text">{{ step.analogy }}</span>
</div>
</div>
</transition>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const active = ref(-1)
const steps = [
{
icon: '👆',
name: '双击图标',
brief: '用户触发启动请求,操作系统开始响应',
detail: '你双击桌面上的浏览器图标时,操作系统的窗口管理器捕获这个鼠标事件,通过文件关联表查找该图标对应的可执行文件路径。',
items: [
{ icon: '🖱️', label: '鼠标事件捕获', desc: '窗口管理器检测到双击动作,识别点击目标' },
{ icon: '🔗', label: '快捷方式解析', desc: '读取 .lnkWindows)或 .desktopLinux)文件中的目标路径' },
{ icon: '📂', label: '文件关联查找', desc: '在注册表或 MIME 数据库中找到对应的可执行文件' }
],
analogy: '就像你按下遥控器的开机键,电视先要识别你按的是哪个按钮,再决定执行什么操作。'
},
{
icon: '🔍',
name: '查找可执行文件',
brief: '根据文件关联,找到浏览器的 .exe 或可执行文件',
detail: '操作系统根据路径在硬盘上定位浏览器的可执行文件(如 chrome.exe),验证文件完整性和权限,准备加载。',
items: [
{ icon: '📋', label: '路径解析', desc: '将快捷方式中的路径转换为硬盘上的实际文件位置' },
{ icon: '🔒', label: '权限检查', desc: '验证当前用户是否有执行该文件的权限' },
{ icon: '✅', label: '签名验证', desc: '检查数字签名确认文件未被篡改(Windows UAC' }
],
analogy: '好比你要找一本书,先查图书馆目录(路径),确认你有借阅权限(权限检查),再确认书没有被损坏(签名验证)。'
},
{
icon: '📋',
name: '创建浏览器进程',
brief: '为浏览器创建一个新的进程,分配进程 ID',
detail: '操作系统内核调用 fork()+exec()Linux)或 CreateProcess()Windows),在进程表中创建新条目,分配唯一的 PID,建立进程控制块(PCB)。',
items: [
{ icon: '🆔', label: '分配 PID', desc: '为新进程分配唯一的进程标识符' },
{ icon: '📊', label: '创建 PCB', desc: '记录进程状态、优先级、寄存器上下文等元信息' },
{ icon: '🧠', label: '分配虚拟地址空间', desc: '为进程创建独立的 4GB(32位)虚拟内存空间' },
{ icon: '📑', label: '初始化文件描述符', desc: '打开 stdin/stdout/stderr 三个标准 I/O 通道' }
],
analogy: '就像新生儿出生要办户口——分配身份证号(PID)、建立档案(PCB)、分配住房(内存空间)。'
},
{
icon: '💾',
name: '加载代码到内存',
brief: '把浏览器的程序代码从硬盘读取到内存中',
detail: '操作系统的加载器(Loader)解析可执行文件格式(PE/ELF),将代码段、数据段映射到虚拟内存,并加载所需的动态链接库(DLL/SO)。',
items: [
{ icon: '📦', label: '解析文件格式', desc: '读取 PEWindows)或 ELFLinux)文件头,确定各段位置' },
{ icon: '🗺️', label: '内存映射', desc: '将 .text(代码)、.data(数据)、.bss 段映射到虚拟地址' },
{ icon: '🔗', label: '动态链接', desc: '加载 DLL/SO 共享库,解析函数符号引用' },
{ icon: '📍', label: '重定位', desc: '修正代码中的绝对地址引用,适配实际加载位置' }
],
analogy: '好比搬家——把家具(代码)从仓库(硬盘)搬到新房(内存),还要接通水电(链接库)。'
},
{
icon: '🚀',
name: '初始化各模块',
brief: '启动主线程、渲染引擎、网络引擎、JS 引擎等',
detail: '浏览器的 main() 函数开始执行,依次初始化多进程架构中的各个核心模块:Browser 主进程、GPU 进程、网络进程等。',
items: [
{ icon: '🧵', label: '主线程启动', desc: '初始化消息循环(Event Loop),处理 UI 事件和任务调度' },
{ icon: '🎨', label: '渲染引擎', desc: '初始化 Blink/Gecko 引擎,准备解析 HTML/CSS' },
{ icon: '🌐', label: '网络模块', desc: '启动网络栈,初始化 DNS 缓存、连接池、Cookie 管理' },
{ icon: '⚡', label: 'JS 引擎', desc: '初始化 V8/SpiderMonkey,编译内置 JavaScript 代码' }
],
analogy: '就像一家餐厅开业前——厨房(渲染)、前台(UI)、外卖(网络)、收银(JS)各部门同时准备就绪。'
},
{
icon: '🖼️',
name: '显示浏览器窗口',
brief: '所有模块就绪,浏览器界面呈现在屏幕上',
detail: '浏览器向操作系统请求创建窗口,GPU 进程完成界面的合成与光栅化,最终将像素数据提交给显卡,浏览器窗口出现在屏幕上。',
items: [
{ icon: '🪟', label: '创建窗口', desc: '调用系统 API 创建原生窗口,设置大小和位置' },
{ icon: '🎨', label: 'UI 绘制', desc: '渲染地址栏、标签页、工具栏等浏览器 Chrome 界面' },
{ icon: '🖥️', label: 'GPU 合成', desc: '将各图层合成为最终画面,提交给显卡输出' },
{ icon: '✨', label: '加载首页', desc: '打开新标签页或恢复上次会话,浏览器进入可用状态' }
],
analogy: '幕布拉开,灯光亮起——舞台(窗口)搭好了,演员(界面元素)就位,等待观众(你)的第一次操作。'
}
]
</script>
<style scoped>
.launch-demo {
border: 1px solid var(--vp-c-divider);
border-radius: 10px;
background: var(--vp-c-bg-soft);
padding: 1.2rem;
margin: 1rem 0;
}
.demo-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
}
.demo-icon { font-size: 1.2rem; }
.demo-title {
font-size: 0.85rem;
font-weight: 700;
color: var(--vp-c-text-1);
}
.demo-hint {
font-size: 0.65rem;
color: var(--vp-c-text-3);
margin-left: auto;
}
.timeline { display: flex; flex-direction: column; }
.timeline-item {
display: flex;
gap: 0.8rem;
cursor: pointer;
}
.marker-col {
display: flex;
flex-direction: column;
align-items: center;
width: 2rem;
flex-shrink: 0;
}
.dot {
width: 1.8rem;
height: 1.8rem;
border-radius: 50%;
background: var(--vp-c-bg);
border: 2px solid var(--vp-c-divider);
color: var(--vp-c-text-3);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.7rem;
font-weight: 700;
transition: all 0.3s;
}
.timeline-item.active .dot {
background: var(--vp-c-brand);
border-color: var(--vp-c-brand);
color: white;
transform: scale(1.15);
box-shadow: 0 0 0 4px var(--vp-c-brand-soft);
}
.timeline-item.done .dot {
background: #10b981;
border-color: #10b981;
color: white;
}
.check { font-size: 0.65rem; }
.line {
flex: 1;
width: 2px;
background: var(--vp-c-divider);
min-height: 0.8rem;
transition: background 0.3s;
}
.timeline-item.done .line { background: #10b981; opacity: 0.5; }
.timeline-item.active .line { background: var(--vp-c-brand); opacity: 0.4; }
.card {
flex: 1;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 0.7rem 0.9rem;
margin-bottom: 0.5rem;
transition: all 0.25s;
}
.timeline-item.active .card {
border-color: var(--vp-c-brand);
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
}
.card-header {
display: flex;
align-items: center;
gap: 0.5rem;
}
.step-icon { font-size: 1.2rem; }
.card-titles { flex: 1; }
.step-name {
font-size: 0.78rem;
font-weight: 700;
color: var(--vp-c-text-1);
}
.step-brief {
font-size: 0.68rem;
color: var(--vp-c-text-3);
margin-top: 0.1rem;
line-height: 1.4;
}
.expand-icon {
font-size: 0.7rem;
color: var(--vp-c-text-3);
transition: transform 0.2s;
}
.card-detail {
margin-top: 0.7rem;
padding-top: 0.7rem;
border-top: 1px dashed var(--vp-c-divider);
}
.detail-desc {
font-size: 0.72rem;
color: var(--vp-c-text-2);
line-height: 1.6;
margin-bottom: 0.6rem;
}
.detail-visual {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem;
}
.visual-item {
display: flex;
align-items: flex-start;
gap: 0.4rem;
background: var(--vp-c-bg-soft);
border-radius: 6px;
padding: 0.45rem 0.55rem;
}
.vi-icon { font-size: 0.9rem; flex-shrink: 0; margin-top: 0.05rem; }
.vi-text { display: flex; flex-direction: column; }
.vi-label {
font-size: 0.68rem;
font-weight: 600;
color: var(--vp-c-text-1);
}
.vi-desc {
font-size: 0.62rem;
color: var(--vp-c-text-3);
line-height: 1.4;
margin-top: 0.1rem;
}
.analogy {
display: flex;
align-items: flex-start;
gap: 0.4rem;
margin-top: 0.6rem;
padding: 0.5rem 0.6rem;
background: var(--vp-c-brand-soft);
border-radius: 6px;
}
.analogy-icon { font-size: 0.85rem; flex-shrink: 0; }
.analogy-text {
font-size: 0.66rem;
color: var(--vp-c-text-2);
line-height: 1.5;
font-style: italic;
}
.slide-enter-active, .slide-leave-active {
transition: all 0.3s ease;
overflow: hidden;
}
.slide-enter-from, .slide-leave-to {
opacity: 0;
max-height: 0;
margin-top: 0;
padding-top: 0;
}
.slide-enter-to, .slide-leave-from {
opacity: 1;
max-height: 30rem;
}
@media (max-width: 640px) {
.detail-visual { grid-template-columns: 1fr; }
.demo-hint { display: none; }
}
</style>