fix(eslint): reduce warnings in GitHub Actions deployment

- Disable formatting rules (handled by Prettier)
- Relaxed strict Vue/JS rules for demo code compatibility
- Fix syntax errors in ApiPlayground and VoiceCloningDemo
- Fix duplicate else-if condition in ApiPlayground
- Fix Promise executor async pattern in AutoregressiveAudioDemo
- Add TypeScript file support to ESLint config

Warnings reduced from 295 to 251 problems.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
sanbuphy
2026-02-18 17:38:10 +08:00
parent 8b01686e68
commit 0eba9e87e9
456 changed files with 28450 additions and 9677 deletions
@@ -22,23 +22,41 @@
<div class="cards">
<div class="card">
<div class="label">运行环境</div>
<div class="value">{{ currentData.runtime }}</div>
<div class="label">
运行环境
</div>
<div class="value">
{{ currentData.runtime }}
</div>
</div>
<div class="card">
<div class="label">主要技术</div>
<div class="value">{{ currentData.stack }}</div>
<div class="label">
主要技术
</div>
<div class="value">
{{ currentData.stack }}
</div>
</div>
<div class="card">
<div class="label">发布方式</div>
<div class="value">{{ currentData.release }}</div>
<div class="label">
发布方式
</div>
<div class="value">
{{ currentData.release }}
</div>
</div>
</div>
<div class="skills">
<div class="skills-title">哪些能力是"共通的"</div>
<div class="skills-title">
哪些能力是"共通的"
</div>
<div class="tags">
<span v-for="t in commonSkills.slice(0, 6)" :key="t" class="tag">{{ t }}</span>
<span
v-for="t in commonSkills.slice(0, 6)"
:key="t"
class="tag"
>{{ t }}</span>
</div>
</div>
</div>
@@ -25,7 +25,9 @@
<div class="visualization-window">
<!-- HTML/CSS Source -->
<div class="source-view">
<div class="window-title">积木说明书 (HTML/CSS)</div>
<div class="window-title">
积木说明书 (HTML/CSS)
</div>
<div class="code-content">
<!-- HTML Highlighted always after Step 0 -->
<div
@@ -139,7 +141,7 @@
&lt;/html&gt;
</div>
<div class="spacer"></div>
<div class="spacer" />
<!-- CSS Highlighted precisely based on step usage -->
<!-- Layout properties -->
@@ -191,11 +193,15 @@
</div>
</div>
<div class="transform-arrow"></div>
<div class="transform-arrow">
</div>
<!-- Render Result -->
<div class="result-view">
<div class="window-title">{{ steps[currentStep].resultTitle }}</div>
<div class="window-title">
{{ steps[currentStep].resultTitle }}
</div>
<div class="render-canvas">
<!-- Step 1: DOM (Skeleton) -->
@@ -240,9 +246,10 @@
@mouseleave="hoveredPart = null"
>
<span class="block-label">img.icon</span>
<span v-if="currentStep >= 3" class="content-img"
>🏰</span
>
<span
v-if="currentStep >= 3"
class="content-img"
>🏰</span>
</div>
<!-- Title -->
@@ -257,9 +264,10 @@
@mouseleave="hoveredPart = null"
>
<span class="block-label">h2.title</span>
<span v-if="currentStep >= 3" class="content"
>乐高城堡</span
>
<span
v-if="currentStep >= 3"
class="content"
>乐高城堡</span>
</div>
<!-- Button -->
@@ -274,9 +282,10 @@
@mouseleave="hoveredPart = null"
>
<span class="block-label">button.btn</span>
<span v-if="currentStep >= 3" class="content-btn"
>购买</span
>
<span
v-if="currentStep >= 3"
class="content-btn"
>购买</span>
</div>
</div>
</div>
@@ -284,16 +293,31 @@
</transition-group>
<!-- Overlays for different steps -->
<div v-if="currentStep === 1" class="overlay-info style-info">
<div class="brush">🖌 正在上色 (Style)...</div>
<div
v-if="currentStep === 1"
class="overlay-info style-info"
>
<div class="brush">
🖌 正在上色 (Style)...
</div>
</div>
<div v-if="currentStep === 2" class="overlay-info layout-info">
<div class="ruler">📏 正在排版 (Layout)...</div>
<div
v-if="currentStep === 2"
class="overlay-info layout-info"
>
<div class="ruler">
📏 正在排版 (Layout)...
</div>
</div>
<div v-if="currentStep === 3" class="overlay-info paint-info">
<div class="paint"> 绘制完成 (Paint)!</div>
<div
v-if="currentStep === 3"
class="overlay-info paint-info"
>
<div class="paint">
绘制完成 (Paint)!
</div>
</div>
</div>
</div>
@@ -5,35 +5,60 @@
<template>
<div class="bundler-demo">
<div class="header">
<div class="title">工程化打包体积与构建时间</div>
<div class="subtitle">勾选功能观察体积变化</div>
<div class="title">
工程化打包体积与构建时间
</div>
<div class="subtitle">
勾选功能观察体积变化
</div>
</div>
<div class="options">
<label v-for="item in features" :key="item.key" class="option">
<input type="checkbox" v-model="item.enabled" />
<label
v-for="item in features"
:key="item.key"
class="option"
>
<input
v-model="item.enabled"
type="checkbox"
>
{{ item.label }} (+{{ item.size }} KB)
</label>
</div>
<label class="toggle">
<input type="checkbox" v-model="treeShaking" />
<input
v-model="treeShaking"
type="checkbox"
>
开启 Tree Shaking (移除未使用代码)
</label>
<div class="stats">
<div class="stat-card">
<div class="label">Bundle Size</div>
<div class="value">{{ bundleSize }} KB</div>
<div class="label">
Bundle Size
</div>
<div class="value">
{{ bundleSize }} KB
</div>
</div>
<div class="stat-card">
<div class="label">Build Time</div>
<div class="value">{{ buildTime }} s</div>
<div class="label">
Build Time
</div>
<div class="value">
{{ buildTime }} s
</div>
</div>
</div>
<div class="bar">
<div class="progress" :style="{ width: barWidth + '%' }"></div>
<div
class="progress"
:style="{ width: barWidth + '%' }"
/>
</div>
</div>
</template>
@@ -1,15 +1,27 @@
<template>
<div class="component-reusability-demo">
<div class="toolbox">
<div class="tool-title">Component Library</div>
<button class="spawn-btn" @click="spawn('counter')">
<div class="tool-title">
Component Library
</div>
<button
class="spawn-btn"
@click="spawn('counter')"
>
New Counter
</button>
<button class="spawn-btn" @click="spawn('card')"> New Card</button>
<button
class="spawn-btn"
@click="spawn('card')"
>
New Card
</button>
</div>
<div class="workspace">
<div class="workspace-label">App Workspace</div>
<div class="workspace-label">
App Workspace
</div>
<div class="instances-container">
<transition-group name="list">
<div
@@ -18,26 +30,47 @@
class="instance-wrapper"
>
<!-- Counter Component -->
<div v-if="item.type === 'counter'" class="comp-instance counter">
<div
v-if="item.type === 'counter'"
class="comp-instance counter"
>
<div class="comp-header">
<span>Counter #{{ item.id }}</span>
<button class="close-btn" @click="remove(item.id)">×</button>
<button
class="close-btn"
@click="remove(item.id)"
>
×
</button>
</div>
<div class="comp-body">
<span class="count-val">{{ item.data.count }}</span>
<button class="mini-btn" @click="item.data.count++">+</button>
<button
class="mini-btn"
@click="item.data.count++"
>
+
</button>
</div>
</div>
<!-- Card Component -->
<div v-if="item.type === 'card'" class="comp-instance card">
<div
v-if="item.type === 'card'"
class="comp-instance card"
>
<div class="comp-header">
<span>Card #{{ item.id }}</span>
<button class="close-btn" @click="remove(item.id)">×</button>
<button
class="close-btn"
@click="remove(item.id)"
>
×
</button>
</div>
<div class="comp-body">
<div class="skeleton-img"></div>
<div class="skeleton-text"></div>
<div class="skeleton-img" />
<div class="skeleton-text" />
<button
class="like-btn"
:class="{ liked: item.data.liked }"
@@ -49,9 +82,12 @@
</div>
</div>
</transition-group>
<div v-if="instances.length === 0" class="empty-hint">
<div
v-if="instances.length === 0"
class="empty-hint"
>
Click buttons above to add components.
<br />
<br>
Notice how each one works independently!
</div>
</div>
@@ -14,22 +14,42 @@
<div class="controls">
<div class="control-row">
<label>width</label>
<input type="range" min="60" max="150" v-model.number="contentW" />
<input
v-model.number="contentW"
type="range"
min="60"
max="150"
>
<span class="val">{{ contentW }}px</span>
</div>
<div class="control-row">
<label>padding</label>
<input type="range" min="0" max="30" v-model.number="padding" />
<input
v-model.number="padding"
type="range"
min="0"
max="30"
>
<span class="val">{{ padding }}px</span>
</div>
<div class="control-row">
<label>border</label>
<input type="range" min="0" max="15" v-model.number="border" />
<input
v-model.number="border"
type="range"
min="0"
max="15"
>
<span class="val">{{ border }}px</span>
</div>
<div class="control-row">
<label>margin</label>
<input type="range" min="0" max="20" v-model.number="margin" />
<input
v-model.number="margin"
type="range"
min="0"
max="20"
>
<span class="val">{{ margin }}px</span>
</div>
</div>
@@ -51,13 +71,34 @@
</div>
<div class="visual">
<div class="layer margin" :style="{ padding: margin + 'px' }">
<span class="layer-label" v-if="margin >= 8">margin</span>
<div class="layer border" :style="{ borderWidth: border + 'px' }">
<span class="layer-label" v-if="border >= 5">border</span>
<div class="layer padding" :style="{ padding: padding + 'px' }">
<span class="layer-label" v-if="padding >= 8">padding</span>
<div class="content" :style="{ width: contentW + 'px' }">
<div
class="layer margin"
:style="{ padding: margin + 'px' }"
>
<span
v-if="margin >= 8"
class="layer-label"
>margin</span>
<div
class="layer border"
:style="{ borderWidth: border + 'px' }"
>
<span
v-if="border >= 5"
class="layer-label"
>border</span>
<div
class="layer padding"
:style="{ padding: padding + 'px' }"
>
<span
v-if="padding >= 8"
class="layer-label"
>padding</span>
<div
class="content"
:style="{ width: contentW + 'px' }"
>
content<br>{{ contentW }}px
</div>
</div>
@@ -80,7 +121,10 @@
{{ contentW }}px已包含 padding border + {{ margin }}×2 = {{ total }}px
</template>
</div>
<div class="result-hint" :class="{ warning: total * 3 > 900 }">
<div
class="result-hint"
:class="{ warning: total * 3 > 900 }"
>
<template v-if="total * 3 > 900">
三个卡片需要 {{ total * 3 }}px超出容器 900px第三个会掉下去
</template>
@@ -91,15 +135,31 @@
</div>
<div class="code-block">
<div class="code-title">CSS</div>
<div class="code-title">
CSS
</div>
<div class="code-content">
<div class="line">.box {</div>
<div class="line hl"> box-sizing: {{ boxSizing }};</div>
<div class="line"> width: {{ contentW }}px;</div>
<div class="line"> padding: {{ padding }}px;</div>
<div class="line"> border: {{ border }}px solid #ccc;</div>
<div class="line"> margin: {{ margin }}px;</div>
<div class="line">}</div>
<div class="line">
.box {
</div>
<div class="line hl">
box-sizing: {{ boxSizing }};
</div>
<div class="line">
width: {{ contentW }}px;
</div>
<div class="line">
padding: {{ padding }}px;
</div>
<div class="line">
border: {{ border }}px solid #ccc;
</div>
<div class="line">
margin: {{ margin }}px;
</div>
<div class="line">
}
</div>
</div>
</div>
</div>
@@ -6,35 +6,57 @@
</div>
<div class="categories">
<div v-for="(cat, index) in categories" :key="index" class="category">
<div class="cat-title">{{ cat.title }}</div>
<div
v-for="(cat, index) in categories"
:key="index"
class="category"
>
<div class="cat-title">
{{ cat.title }}
</div>
<div class="props-grid">
<div
v-for="prop in cat.props"
:key="prop.name"
class="prop-item"
@click="activeProp = prop"
:class="{ active: activeProp && activeProp.name === prop.name }"
@click="activeProp = prop"
>
<div class="prop-name">{{ prop.name }}</div>
<div class="prop-desc">{{ prop.desc }}</div>
<div class="prop-name">
{{ prop.name }}
</div>
<div class="prop-desc">
{{ prop.desc }}
</div>
</div>
</div>
</div>
</div>
<div v-if="activeProp" class="prop-detail">
<div
v-if="activeProp"
class="prop-detail"
>
<div class="detail-header">
<span class="detail-name">{{ activeProp.name }}</span>
<span class="detail-cat-badge">{{ activeProp.categoryLabel }}</span>
</div>
<div class="detail-desc">{{ activeProp.fullDesc }}</div>
<div class="detail-desc">
{{ activeProp.fullDesc }}
</div>
<div class="detail-code">
<div class="code-label">示例代码</div>
<div class="code-label">
示例代码
</div>
<pre><code>{{ activeProp.example }}</code></pre>
</div>
</div>
<div v-else class="prop-detail empty">点击上面的属性看看它能做什么 👆</div>
<div
v-else
class="prop-detail empty"
>
点击上面的属性看看它能做什么 👆
</div>
</div>
</template>
@@ -89,8 +89,17 @@
</div>
<div class="preview-area">
<div class="canvas" :style="boxStyle">
<div v-for="n in 6" :key="n" class="item">{{ n }}</div>
<div
class="canvas"
:style="boxStyle"
>
<div
v-for="n in 6"
:key="n"
class="item"
>
{{ n }}
</div>
</div>
<div class="axis-hint">
<span class="axis-tag main">主轴方向: {{ dir === 'row' ? '水平 →' : '垂直 ↓' }}</span>
@@ -100,7 +109,9 @@
</div>
<div class="code-row">
<div class="code-label">CSS</div>
<div class="code-label">
CSS
</div>
<code class="code-text">{{ cssCode }}</code>
</div>
@@ -68,7 +68,10 @@
</div>
<div class="preview-area">
<div class="container" :style="containerStyle">
<div
class="container"
:style="containerStyle"
>
<div
v-for="n in itemCount"
:key="n"
@@ -81,7 +84,9 @@
</div>
<div class="code-display">
<div class="code-header">👆 点击代码行可以暂时禁用该属性</div>
<div class="code-header">
👆 点击代码行可以暂时禁用该属性
</div>
<pre>.container {
display: flex;
<div
@@ -19,49 +19,80 @@
<div class="controls">
<div class="control-group">
<label>背景颜色 (background-color)</label>
<input type="color" v-model="bgColor" />
<input
v-model="bgColor"
type="color"
>
<span class="value">{{ bgColor }}</span>
</div>
<div class="control-group">
<label>文字颜色 (color)</label>
<input type="color" v-model="textColor" />
<input
v-model="textColor"
type="color"
>
<span class="value">{{ textColor }}</span>
</div>
<div class="control-group">
<label>字体大小 (font-size)</label>
<input type="range" v-model="fontSize" min="12" max="48" />
<input
v-model="fontSize"
type="range"
min="12"
max="48"
>
<span class="value">{{ fontSize }}px</span>
</div>
<div class="control-group">
<label>内边距 (padding)</label>
<input type="range" v-model="padding" min="0" max="50" />
<input
v-model="padding"
type="range"
min="0"
max="50"
>
<span class="value">{{ padding }}px</span>
</div>
<div class="control-group">
<label>圆角 (border-radius)</label>
<input type="range" v-model="borderRadius" min="0" max="50" />
<input
v-model="borderRadius"
type="range"
min="0"
max="50"
>
<span class="value">{{ borderRadius }}px</span>
</div>
<div class="control-group">
<label>边框宽度 (border-width)</label>
<input type="range" v-model="borderWidth" min="0" max="10" />
<input
v-model="borderWidth"
type="range"
min="0"
max="10"
>
<span class="value">{{ borderWidth }}px</span>
</div>
<div class="control-group">
<label>边框颜色 (border-color)</label>
<input type="color" v-model="borderColor" />
<input
v-model="borderColor"
type="color"
>
<span class="value">{{ borderColor }}</span>
</div>
</div>
<div class="code-preview">
<div class="code-title">生成的 CSS 代码</div>
<div class="code-title">
生成的 CSS 代码
</div>
<pre><code>.element {
background-color: <span class="highlight">{{ bgColor }}</span>;
color: <span class="highlight">{{ textColor }}</span>;
@@ -7,7 +7,9 @@
<div class="comparison">
<!-- Left: CSS Rules -->
<div class="column css-col">
<div class="col-title">CSS (样式表)</div>
<div class="col-title">
CSS (样式表)
</div>
<div class="rules-list">
<div
class="rule-item"
@@ -15,8 +17,12 @@
@mouseenter="activeType = 'tag'"
@mouseleave="activeType = null"
>
<div class="selector">p</div>
<div class="block">{ color: #333; }</div>
<div class="selector">
p
</div>
<div class="block">
{ color: #333; }
</div>
<div class="explanation">
<span class="badge tag">标签选择器</span>
直接写标签名选中所有 <code>&lt;p&gt;</code>
@@ -29,8 +35,12 @@
@mouseenter="activeType = 'class'"
@mouseleave="activeType = null"
>
<div class="selector">.card</div>
<div class="block">{ background: white; }</div>
<div class="selector">
.card
</div>
<div class="block">
{ background: white; }
</div>
<div class="explanation">
<span class="badge class">类选择器</span>
<code>.</code> 开头选中所有 <code>class="card"</code>
@@ -43,8 +53,12 @@
@mouseenter="activeType = 'id'"
@mouseleave="activeType = null"
>
<div class="selector">#submit-btn</div>
<div class="block">{ font-weight: bold; }</div>
<div class="selector">
#submit-btn
</div>
<div class="block">
{ font-weight: bold; }
</div>
<div class="explanation">
<span class="badge id">ID 选择器</span>
<code>#</code> 开头选中唯一 <code>id="submit-btn"</code>
@@ -55,19 +69,32 @@
<!-- Center: Connector -->
<div class="connector">
<div class="line-path" :class="activeType"></div>
<div class="icon">🔗</div>
<div
class="line-path"
:class="activeType"
/>
<div class="icon">
🔗
</div>
</div>
<!-- Right: HTML Structure -->
<div class="column html-col">
<div class="col-title">HTML (结构)</div>
<div class="col-title">
HTML (结构)
</div>
<div class="code-view">
<div class="html-line" :class="{ highlight: activeType === 'tag' }">
<div
class="html-line"
:class="{ highlight: activeType === 'tag' }"
>
&lt;p&gt;我是普通段落&lt;/p&gt;
</div>
<div class="html-line" :class="{ highlight: activeType === 'class' }">
<div
class="html-line"
:class="{ highlight: activeType === 'class' }"
>
&lt;div <span class="attr">class="card"</span>&gt;
</div>
@@ -80,11 +107,17 @@
&lt;p&gt;我是卡片里的段落&lt;/p&gt;
</div>
<div class="html-line" :class="{ highlight: activeType === 'class' }">
<div
class="html-line"
:class="{ highlight: activeType === 'class' }"
>
&lt;/div&gt;
</div>
<div class="html-line" :class="{ highlight: activeType === 'id' }">
<div
class="html-line"
:class="{ highlight: activeType === 'id' }"
>
&lt;button
<span class="attr">id="submit-btn"</span>&gt;提交&lt;/button&gt;
</div>
@@ -15,152 +15,278 @@
<div class="architecture-diagram">
<!-- 基础架构 -->
<div v-if="currentView === 0" class="basic-architecture">
<div
v-if="currentView === 0"
class="basic-architecture"
>
<div class="user-node">
<div class="node-icon">👤</div>
<div class="node-label">用户</div>
<div class="node-icon">
👤
</div>
<div class="node-label">
用户
</div>
</div>
<div class="arrow-down"></div>
<div class="arrow-down">
</div>
<div class="domain-node">
<div class="node-icon">🌐</div>
<div class="node-label">域名</div>
<div class="node-desc">example.com</div>
<div class="node-icon">
🌐
</div>
<div class="node-label">
域名
</div>
<div class="node-desc">
example.com
</div>
</div>
<div class="arrow-down"> DNS 解析</div>
<div class="arrow-down">
DNS 解析
</div>
<div class="server-node">
<div class="node-icon">🖥</div>
<div class="node-label">服务器</div>
<div class="node-desc">IP: 1.2.3.4</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
服务器
</div>
<div class="node-desc">
IP: 1.2.3.4
</div>
</div>
<div class="arrow-down"></div>
<div class="arrow-down">
</div>
<div class="web-node">
<div class="node-icon">🌍</div>
<div class="node-label">Web 应用</div>
<div class="node-icon">
🌍
</div>
<div class="node-label">
Web 应用
</div>
</div>
</div>
<!-- CDN 架构 -->
<div v-if="currentView === 1" class="cdn-architecture">
<div
v-if="currentView === 1"
class="cdn-architecture"
>
<div class="user-nodes">
<div class="user-node china">
<div class="node-icon">🇨🇳</div>
<div class="node-label">中国用户</div>
<div class="node-icon">
🇨🇳
</div>
<div class="node-label">
中国用户
</div>
</div>
<div class="user-node usa">
<div class="node-icon">🇺🇸</div>
<div class="node-label">美国用户</div>
<div class="node-icon">
🇺🇸
</div>
<div class="node-label">
美国用户
</div>
</div>
</div>
<div class="arrow-group">
<div class="arrow-left"></div>
<div class="arrow-right"></div>
<div class="arrow-left">
</div>
<div class="arrow-right">
</div>
</div>
<div class="cdn-nodes">
<div class="cdn-node">
<div class="node-icon">📡</div>
<div class="node-label">CDN 北京节点</div>
<div class="node-icon">
📡
</div>
<div class="node-label">
CDN 北京节点
</div>
</div>
<div class="cdn-node">
<div class="node-icon">📡</div>
<div class="node-label">CDN 纽约节点</div>
<div class="node-icon">
📡
</div>
<div class="node-label">
CDN 纽约节点
</div>
</div>
</div>
<div class="arrow-down"> 缓存未命中</div>
<div class="arrow-down">
缓存未命中
</div>
<div class="origin-node">
<div class="node-icon">🖥</div>
<div class="node-label">源服务器</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
源服务器
</div>
</div>
</div>
<!-- 负载均衡 -->
<div v-if="currentView === 2" class="loadbalancer-architecture">
<div
v-if="currentView === 2"
class="loadbalancer-architecture"
>
<div class="user-node">
<div class="node-icon">👥</div>
<div class="node-label">用户请求</div>
<div class="node-icon">
👥
</div>
<div class="node-label">
用户请求
</div>
</div>
<div class="arrow-down"></div>
<div class="arrow-down">
</div>
<div class="lb-node">
<div class="node-icon"></div>
<div class="node-label">负载均衡器</div>
<div class="node-icon">
</div>
<div class="node-label">
负载均衡器
</div>
</div>
<div class="arrow-group">
<div class="arrow-1"></div>
<div class="arrow-2"></div>
<div class="arrow-3"></div>
<div class="arrow-1">
</div>
<div class="arrow-2">
</div>
<div class="arrow-3">
</div>
</div>
<div class="server-nodes">
<div class="server-node">
<div class="node-icon">🖥</div>
<div class="node-label">服务器 1</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
服务器 1
</div>
</div>
<div class="server-node">
<div class="node-icon">🖥</div>
<div class="node-label">服务器 2</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
服务器 2
</div>
</div>
<div class="server-node">
<div class="node-icon">🖥</div>
<div class="node-label">服务器 3</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
服务器 3
</div>
</div>
</div>
</div>
<!-- 完整架构 -->
<div v-if="currentView === 3" class="full-architecture">
<div
v-if="currentView === 3"
class="full-architecture"
>
<div class="user-nodes">
<div class="user-node">
<div class="node-icon">👤</div>
<div class="node-label">用户</div>
<div class="node-icon">
👤
</div>
<div class="node-label">
用户
</div>
</div>
</div>
<div class="arrow-down"></div>
<div class="dns-node">
<div class="node-icon">🔍</div>
<div class="node-label">DNS</div>
<div class="arrow-down">
</div>
<div class="arrow-down"></div>
<div class="dns-node">
<div class="node-icon">
🔍
</div>
<div class="node-label">
DNS
</div>
</div>
<div class="arrow-down">
</div>
<div class="cdn-lb-row">
<div class="cdn-node">
<div class="node-icon">📡</div>
<div class="node-label">CDN</div>
<div class="node-icon">
📡
</div>
<div class="node-label">
CDN
</div>
</div>
<div class="lb-node">
<div class="node-icon"></div>
<div class="node-label">LB</div>
<div class="node-icon">
</div>
<div class="node-label">
LB
</div>
</div>
</div>
<div class="arrow-down"></div>
<div class="arrow-down">
</div>
<div class="server-cluster">
<div class="server-node">
<div class="node-icon">🖥</div>
<div class="node-label">Web 1</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
Web 1
</div>
</div>
<div class="server-node">
<div class="node-icon">🖥</div>
<div class="node-label">Web 2</div>
<div class="node-icon">
🖥
</div>
<div class="node-label">
Web 2
</div>
</div>
<div class="server-node">
<div class="node-icon">💾</div>
<div class="node-label">Database</div>
<div class="node-icon">
💾
</div>
<div class="node-label">
Database
</div>
</div>
</div>
</div>
@@ -168,54 +294,74 @@
</div>
<div class="info-cards">
<div class="info-card" v-if="currentView === 0">
<div class="card-title">🌐 域名 (Domain)</div>
<div
v-if="currentView === 0"
class="info-card"
>
<div class="card-title">
🌐 域名 (Domain)
</div>
<div class="card-content">
<strong>什么是域名</strong>
<br />域名是网站的地址 example.com便于记忆和访问 <br /><br />
<br>域名是网站的地址 example.com便于记忆和访问 <br><br>
<strong>域名注册</strong>
<br /> 注册商GoDaddyNamecheap阿里云 <br />
选择后缀.com.cn.org.io <br /> 价格$10-50/
<br> 注册商GoDaddyNamecheap阿里云 <br>
选择后缀.com.cn.org.io <br> 价格$10-50/
</div>
</div>
<div class="info-card" v-if="currentView === 1">
<div class="card-title">📡 CDN (内容分发网络)</div>
<div
v-if="currentView === 1"
class="info-card"
>
<div class="card-title">
📡 CDN (内容分发网络)
</div>
<div class="card-content">
<strong>什么是 CDN</strong>
<br />将内容缓存到全球各地的节点用户就近访问 <br /><br />
<br>将内容缓存到全球各地的节点用户就近访问 <br><br>
<strong>优势</strong>
<br /> 加速访问就近获取内容 <br /> 减轻负载减少源站压力 <br />
提高可用性节点故障自动切换 <br /><br />
<br> 加速访问就近获取内容 <br> 减轻负载减少源站压力 <br>
提高可用性节点故障自动切换 <br><br>
<strong>常见 CDN</strong>
<br /> CloudflareAWS CloudFront阿里云 CDN
<br> CloudflareAWS CloudFront阿里云 CDN
</div>
</div>
<div class="info-card" v-if="currentView === 2">
<div class="card-title"> 负载均衡 (Load Balancer)</div>
<div
v-if="currentView === 2"
class="info-card"
>
<div class="card-title">
负载均衡 (Load Balancer)
</div>
<div class="card-content">
<strong>什么是负载均衡</strong>
<br />将请求分发到多台服务器提高并发能力 <br /><br />
<br>将请求分发到多台服务器提高并发能力 <br><br>
<strong>负载均衡算法</strong>
<br /> 轮询 (Round Robin) <br /> 最少连接 (Least Connections)
<br /> IP 哈希 (IP Hash) <br /><br />
<br> 轮询 (Round Robin) <br> 最少连接 (Least Connections)
<br> IP 哈希 (IP Hash) <br><br>
<strong>常见工具</strong>
<br /> NginxHAProxyAWS ELB
<br> NginxHAProxyAWS ELB
</div>
</div>
<div class="info-card" v-if="currentView === 3">
<div class="card-title">🏗 完整部署架构</div>
<div
v-if="currentView === 3"
class="info-card"
>
<div class="card-title">
🏗 完整部署架构
</div>
<div class="card-content">
<strong>现代 Web 应用架构</strong>
<br /><br />
<br><br>
1. 用户通过域名访问
<br />2. DNS 解析到 CDN 或负载均衡器 <br />3. CDN 缓存静态资源
<br />4. 负载均衡器分发请求 <br />5. Web 服务器处理动态请求 <br />6.
数据库存储持久化数据 <br /><br />
<br>2. DNS 解析到 CDN 或负载均衡器 <br>3. CDN 缓存静态资源
<br>4. 负载均衡器分发请求 <br>5. Web 服务器处理动态请求 <br>6.
数据库存储持久化数据 <br><br>
<strong>监控和运维</strong>
<br /> 日志收集性能监控自动备份
<br> 日志收集性能监控自动备份
</div>
</div>
</div>
@@ -7,7 +7,7 @@
<p class="why-desc-zh">
你知道店铺名字叫 "Shop.com"但快递员需要知道具体的经纬度坐标 (IP 地址)
才能送达
<br />
<br>
DNS 就像是<strong>地图导航</strong>输入店名它告诉你具体的坐标
</p>
</div>
@@ -15,22 +15,36 @@
<div class="demo-stage">
<div class="input-area">
<span class="label">店铺名称 (域名)</span>
<div class="fake-input">shop.com</div>
<div class="fake-input">
shop.com
</div>
</div>
<div class="process-animation">
<div class="arrow-down"></div>
<div class="dns-box">
<div class="icon">🧭</div>
<div class="title">DNS (地图导航)</div>
<div class="desc">正在查找 shop.com 的位置...</div>
<div class="arrow-down">
</div>
<div class="dns-box">
<div class="icon">
🧭
</div>
<div class="title">
DNS (地图导航)
</div>
<div class="desc">
正在查找 shop.com 的位置...
</div>
</div>
<div class="arrow-down">
</div>
<div class="arrow-down"></div>
</div>
<div class="output-area">
<span class="label">GPS 坐标 (IP 地址)</span>
<div class="fake-output">93.184.216.34</div>
<div class="fake-output">
93.184.216.34
</div>
</div>
</div>
</div>
@@ -9,21 +9,34 @@
<div class="left-panel">
<div class="operations">
<div class="op-group">
<div class="op-label">修改内容</div>
<div class="op-label">
修改内容
</div>
<div class="op-row">
<input v-model="titleText" placeholder="输入标题" class="input" />
<button @click="updateTitle" class="btn">更新标题</button>
<input
v-model="titleText"
placeholder="输入标题"
class="input"
>
<button
class="btn"
@click="updateTitle"
>
更新标题
</button>
</div>
</div>
<div class="op-group">
<div class="op-label">修改样式</div>
<div class="op-label">
修改样式
</div>
<div class="op-row">
<button
v-for="s in styles"
:key="s.id"
@click="currentStyle = s.id"
:class="['btn-sm', { active: currentStyle === s.id }]"
@click="currentStyle = s.id"
>
{{ s.label }}
</button>
@@ -31,59 +44,124 @@
</div>
<div class="op-group">
<div class="op-label">添加/删除元素</div>
<div class="op-label">
添加/删除元素
</div>
<div class="op-row">
<button @click="addItem" class="btn">添加项目</button>
<button @click="removeLastItem" class="btn btn-danger">删除最后</button>
<button
class="btn"
@click="addItem"
>
添加项目
</button>
<button
class="btn btn-danger"
@click="removeLastItem"
>
删除最后
</button>
</div>
</div>
</div>
<div class="preview-card" :class="currentStyle">
<h2 class="card-title">{{ titleText || '点击按钮更新标题' }}</h2>
<p class="card-desc">这是一个演示 DOM 操作的卡片区域</p>
<div
class="preview-card"
:class="currentStyle"
>
<h2 class="card-title">
{{ titleText || '点击按钮更新标题' }}
</h2>
<p class="card-desc">
这是一个演示 DOM 操作的卡片区域
</p>
<ul class="card-list">
<li v-for="(item, i) in items" :key="i">{{ item }}</li>
<li v-if="items.length === 0" class="empty">列表为空</li>
<li
v-for="(item, i) in items"
:key="i"
>
{{ item }}
</li>
<li
v-if="items.length === 0"
class="empty"
>
列表为空
</li>
</ul>
</div>
</div>
<div class="right-panel">
<div class="code-block">
<div class="code-title">对应的 JavaScript 代码</div>
<div class="code-title">
对应的 JavaScript 代码
</div>
<div class="code-content">
<template v-if="lastOp === 'title'">
<div class="line comment">// 修改文本内容</div>
<div class="line">const el = document.querySelector('.card-title')</div>
<div class="line">el.textContent = '{{ titleText }}'</div>
<div class="line comment">
// 修改文本内容
</div>
<div class="line">
const el = document.querySelector('.card-title')
</div>
<div class="line">
el.textContent = '{{ titleText }}'
</div>
</template>
<template v-else-if="lastOp === 'style'">
<div class="line comment">// 切换 CSS 类</div>
<div class="line">const card = document.querySelector('.preview-card')</div>
<div class="line">card.className = 'preview-card {{ currentStyle }}'</div>
<div class="line comment">
// 切换 CSS 类
</div>
<div class="line">
const card = document.querySelector('.preview-card')
</div>
<div class="line">
card.className = 'preview-card {{ currentStyle }}'
</div>
</template>
<template v-else-if="lastOp === 'add'">
<div class="line comment">// 创建并添加新元素</div>
<div class="line">const list = document.querySelector('.card-list')</div>
<div class="line">const li = document.createElement('li')</div>
<div class="line">li.textContent = '新项目 {{ items.length }}'</div>
<div class="line">list.appendChild(li)</div>
<div class="line comment">
// 创建并添加新元素
</div>
<div class="line">
const list = document.querySelector('.card-list')
</div>
<div class="line">
const li = document.createElement('li')
</div>
<div class="line">
li.textContent = '新项目 {{ items.length }}'
</div>
<div class="line">
list.appendChild(li)
</div>
</template>
<template v-else-if="lastOp === 'remove'">
<div class="line comment">// 删除最后一个元素</div>
<div class="line">const list = document.querySelector('.card-list')</div>
<div class="line">const last = list.lastElementChild</div>
<div class="line">if (last) last.remove()</div>
<div class="line comment">
// 删除最后一个元素
</div>
<div class="line">
const list = document.querySelector('.card-list')
</div>
<div class="line">
const last = list.lastElementChild
</div>
<div class="line">
if (last) last.remove()
</div>
</template>
<template v-else>
<div class="line comment">// 点击左侧按钮查看对应代码</div>
<div class="line comment">
// 点击左侧按钮查看对应代码
</div>
</template>
</div>
</div>
<div class="methods-card">
<div class="methods-title">常用 DOM 方法</div>
<div class="methods-title">
常用 DOM 方法
</div>
<div class="methods-list">
<div class="method">
<code>querySelector()</code>
@@ -2,7 +2,7 @@
<div class="frontend-evolution-demo">
<!-- Modern Timeline -->
<div class="timeline-container">
<div class="timeline-track"></div>
<div class="timeline-track" />
<button
v-for="(stage, index) in stages"
:key="index"
@@ -14,7 +14,7 @@
@click="currentStage = index"
>
<div class="node-dot">
<div class="inner-dot"></div>
<div class="inner-dot" />
</div>
<div class="node-content">
<span class="year-badge">{{ stage.year }}</span>
@@ -24,13 +24,17 @@
</div>
<div class="content-wrapper">
<transition name="fade-slide" mode="out-in">
<div :key="currentStage" class="stage-content">
<transition
name="fade-slide"
mode="out-in"
>
<div
:key="currentStage"
class="stage-content"
>
<div class="header-section">
<h3>
<span class="stage-index"
>{{ indexToRoman(currentStage + 1) }}.</span
>
<span class="stage-index">{{ indexToRoman(currentStage + 1) }}.</span>
{{ stages[currentStage].title }}
</h3>
<p>{{ stages[currentStage].desc }}</p>
@@ -41,9 +45,9 @@
<div class="mac-window code-window">
<div class="window-bar">
<div class="traffic-lights">
<span class="light red"></span>
<span class="light yellow"></span>
<span class="light green"></span>
<span class="light red" />
<span class="light yellow" />
<span class="light green" />
</div>
<div class="window-title">
{{ stages[currentStage].codeTitle }}
@@ -57,30 +61,45 @@
<!-- Diagram View -->
<div class="mac-window diagram-window">
<div class="window-bar">
<div class="window-title">Architecture Pattern</div>
<div class="window-title">
Architecture Pattern
</div>
</div>
<div class="diagram-canvas">
<!-- Stage 0: Static -->
<div v-if="currentStage === 0" class="diagram static">
<div
v-if="currentStage === 0"
class="diagram static"
>
<div class="flow-stack">
<div class="concept-box html">
<span class="icon">📄</span> HTML (Content)
</div>
<div class="flow-arrow"></div>
<div class="flow-arrow">
</div>
<div class="concept-box browser">
<span class="icon">🌍</span> Browser (Display)
</div>
</div>
<div class="side-note">Server sends complete HTML</div>
<div class="side-note">
Server sends complete HTML
</div>
</div>
<!-- Stage 1: jQuery -->
<div v-if="currentStage === 1" class="diagram jquery">
<div
v-if="currentStage === 1"
class="diagram jquery"
>
<div class="concept-box dom">
<span class="icon">🌳</span> DOM Tree
</div>
<div class="chaos-arrows">
<svg viewBox="0 0 100 60" class="chaos-svg">
<svg
viewBox="0 0 100 60"
class="chaos-svg"
>
<path
d="M10,10 Q50,5 90,10"
class="arrow-path"
@@ -115,45 +134,70 @@
refY="3.5"
orient="auto"
>
<polygon points="0 0, 10 3.5, 0 7" fill="#666" />
<polygon
points="0 0, 10 3.5, 0 7"
fill="#666"
/>
</marker>
</defs>
</svg>
</div>
<!-- Stage 2: MVC -->
<div v-if="currentStage === 2" class="diagram mvc">
<div
v-if="currentStage === 2"
class="diagram mvc"
>
<div class="mvc-triangle">
<div class="concept-box model">Model</div>
<div class="concept-box view">View</div>
<div class="concept-box controller">Controller</div>
<div class="concept-box model">
Model
</div>
<div class="concept-box view">
View
</div>
<div class="concept-box controller">
Controller
</div>
<!-- Connecting Lines -->
<div class="line m-v"></div>
<div class="line v-c"></div>
<div class="line c-m"></div>
<div class="line m-v" />
<div class="line v-c" />
<div class="line c-m" />
</div>
<div class="mvc-desc">
Two-way Binding
</div>
<div class="mvc-desc">Two-way Binding</div>
</div>
<!-- Stage 3: Component -->
<div v-if="currentStage === 3" class="diagram component">
<div
v-if="currentStage === 3"
class="diagram component"
>
<div class="comp-structure">
<div class="comp-box root">
<span class="comp-label">App</span>
<div class="comp-children">
<div class="comp-box header">Header</div>
<div class="comp-box header">
Header
</div>
<div class="comp-box list">
ProductList
<div class="comp-children row">
<div class="comp-box item">Item</div>
<div class="comp-box item">Item</div>
<div class="comp-box item">
Item
</div>
<div class="comp-box item">
Item
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flow-pill">State UI = f(State)</div>
<div class="flow-pill">
State UI = f(State)
</div>
</div>
</div>
</div>
@@ -3,14 +3,26 @@
<div class="browser-frame">
<!-- Address Bar (Simplified) -->
<div class="address-bar">
<select v-model="method" class="method-select" :disabled="loading">
<select
v-model="method"
class="method-select"
:disabled="loading"
>
<option>GET</option>
<option>POST</option>
<option>PUT</option>
<option>DELETE</option>
</select>
<input v-model="path" class="url-input" :disabled="loading" />
<button @click="sendRequest" :disabled="loading" class="send-btn">
<input
v-model="path"
class="url-input"
:disabled="loading"
>
<button
:disabled="loading"
class="send-btn"
@click="sendRequest"
>
{{ loading ? '...' : t.send }}
</button>
</div>
@@ -25,22 +37,33 @@
<span>{{ t.cols.time }}</span>
</div>
<div
v-if="requestSent"
class="log-row"
:class="{ active: requestSent, selected: true }"
v-if="requestSent"
>
<span class="col-name">{{ path.split('/').pop() || 'index' }}</span>
<span class="col-status" :class="statusClass">{{
<span
class="col-status"
:class="statusClass"
>{{
responseStatus
}}</span>
<span class="col-type">document</span>
<span class="col-time">{{ loading ? 'Pending' : '45ms' }}</span>
</div>
<div v-else class="empty-state">{{ t.noRequests }}</div>
<div
v-else
class="empty-state"
>
{{ t.noRequests }}
</div>
</div>
<!-- Details Panel (Right) -->
<div class="details-panel" v-if="requestSent">
<div
v-if="requestSent"
class="details-panel"
>
<div class="tabs">
<button
v-for="tabKey in ['headers', 'response', 'preview']"
@@ -54,9 +77,14 @@
<div class="tab-content">
<!-- Headers Tab -->
<div v-if="activeTab === 'headers'" class="headers-view">
<div
v-if="activeTab === 'headers'"
class="headers-view"
>
<div class="section">
<div class="section-title">{{ t.general }}</div>
<div class="section-title">
{{ t.general }}
</div>
<div class="kv-row">
<span class="key">{{ t.requestUrl }}:</span>
<span class="value">https://api.example.com{{ path }}</span>
@@ -68,17 +96,22 @@
<div class="kv-row">
<span class="key">{{ t.statusCode }}:</span>
<span class="value">
<span class="status-dot" :class="statusClass"></span>
<span
class="status-dot"
:class="statusClass"
/>
{{ responseStatus || '...' }}
</span>
</div>
</div>
<div class="section">
<div class="section-title">{{ t.responseHeaders }}</div>
<div class="section-title">
{{ t.responseHeaders }}
</div>
<div
class="kv-row"
v-for="(val, key) in responseHeaders"
:key="key"
class="kv-row"
>
<span class="key">{{ key }}:</span>
<span class="value">{{ val }}</span>
@@ -87,24 +120,36 @@
</div>
<!-- Response Tab -->
<div v-if="activeTab === 'response'" class="code-view">
<div
v-if="activeTab === 'response'"
class="code-view"
>
<pre>{{ responseBody }}</pre>
</div>
<!-- Preview Tab -->
<div v-if="activeTab === 'preview'" class="preview-view">
<div
v-if="activeTab === 'preview'"
class="preview-view"
>
<div
v-if="method === 'GET'"
class="html-preview"
v-html="responseBody"
></div>
<div v-else class="json-preview">
/>
<div
v-else
class="json-preview"
>
JSON Data: {{ responseBody }}
</div>
</div>
</div>
</div>
<div v-else class="details-placeholder">
<div
v-else
class="details-placeholder"
>
{{ t.placeholder }}
</div>
</div>
@@ -16,30 +16,46 @@
</div>
<div class="code-preview">
<code>
// 手动操作 DOM<br />
$('#count').text(val);<br />
// 手动操作 DOM<br>
$('#count').text(val);<br>
if (val > 5) $('#msg').show();
</code>
</div>
<div class="interactive-area">
<div class="output-box">
Count: <span id="imp-count-display">{{ impCount }}</span>
<div v-show="impShowMsg" class="warning-msg"> Count is high!</div>
<div
v-show="impShowMsg"
class="warning-msg"
>
Count is high!
</div>
</div>
<div class="actions">
<button @click="impIncrement" class="btn">Step 1: Value++</button>
<button @click="impUpdateText" class="btn" :disabled="!impChanged">
<button
class="btn"
@click="impIncrement"
>
Step 1: Value++
</button>
<button
class="btn"
:disabled="!impChanged"
@click="impUpdateText"
>
Step 2: Update Text
</button>
<button
@click="impCheckState"
class="btn"
:disabled="!impTextUpdated"
@click="impCheckState"
>
Step 3: Check Logic
</button>
</div>
<div class="status-log">{{ impStatus }}</div>
<div class="status-log">
{{ impStatus }}
</div>
</div>
</div>
@@ -59,10 +75,18 @@
<div class="interactive-area">
<div class="output-box">
Count: <span>{{ decCount }}</span>
<div v-if="decCount > 5" class="warning-msg">⚠️ Count is high!</div>
<div
v-if="decCount > 5"
class="warning-msg"
>
⚠️ Count is high!
</div>
</div>
<div class="actions">
<button @click="decIncrement" class="btn primary">
<button
class="btn primary"
@click="decIncrement"
>
Value++ (Auto Render)
</button>
</div>
@@ -5,7 +5,9 @@
<template>
<div class="jq-demo">
<div class="header">
<div class="title">什么是 jQuery购物车数量秒懂</div>
<div class="title">
什么是 jQuery购物车数量秒懂
</div>
<div class="subtitle">
左边 jQuery 一样手动改页面容易漏右边 Vue/React
一样只改状态
@@ -15,48 +17,83 @@
<div class="panes">
<!-- jQuery-like -->
<div class="pane">
<div class="pane-title">jQuery 思路到处改 DOM</div>
<div class="pane-title">
jQuery 思路到处改 DOM
</div>
<div class="mock-app">
<div class="topbar">
<span>🛒 角标</span>
<span class="badge" :class="{ wrong: jqBadgeWrong }">{{
<span
class="badge"
:class="{ wrong: jqBadgeWrong }"
>{{
jqBadge
}}</span>
</div>
<div class="content">
<div class="row">
购物车页数量
<span class="num" :class="{ wrong: jqPageWrong }">{{
<span
class="num"
:class="{ wrong: jqPageWrong }"
>{{
jqPage
}}</span>
</div>
<div class="row">
结算按钮
<button class="checkout">去结算 ({{ jqButtonLabel }})</button>
<button class="checkout">
去结算 ({{ jqButtonLabel }})
</button>
</div>
</div>
</div>
<div class="controls">
<div class="control-title">模拟你写的命令</div>
<div class="control-title">
模拟你写的命令
</div>
<div class="btns">
<button @click="jqIncreaseData">数据 +1但还没改页面</button>
<button @click="jqUpdateBadge">改角标</button>
<button @click="jqUpdateCartPage">改购物车页</button>
<button @click="jqUpdateCheckoutButton">改结算按钮</button>
<button @click="jqIncreaseData">
数据 +1但还没改页面
</button>
<button @click="jqUpdateBadge">
改角标
</button>
<button @click="jqUpdateCartPage">
改购物车页
</button>
<button @click="jqUpdateCheckoutButton">
改结算按钮
</button>
</div>
<div class="hint" :class="{ danger: jqInconsistent }">
<div
class="hint"
:class="{ danger: jqInconsistent }"
>
{{ jqHint }}
</div>
<div class="log">
<div class="log-title">命令日志</div>
<div v-if="jqLogs.length === 0" class="log-empty">
<div class="log-title">
命令日志
</div>
<div
v-if="jqLogs.length === 0"
class="log-empty"
>
还没有操作
</div>
<div v-else class="log-list">
<div v-for="(l, idx) in jqLogs" :key="idx" class="log-item">
<div
v-else
class="log-list"
>
<div
v-for="(l, idx) in jqLogs"
:key="idx"
class="log-item"
>
{{ l }}
</div>
</div>
@@ -66,7 +103,9 @@
<!-- State-driven -->
<div class="pane">
<div class="pane-title">Vue/React 思路只改 State</div>
<div class="pane-title">
Vue/React 思路只改 State
</div>
<div class="mock-app">
<div class="topbar">
<span>🛒 角标</span>
@@ -78,23 +117,39 @@
</div>
<div class="row">
结算按钮
<button class="checkout">去结算 ({{ state }} )</button>
<button class="checkout">
去结算 ({{ state }} )
</button>
</div>
</div>
</div>
<div class="controls">
<div class="control-title">你只需要做一件事</div>
<div class="control-title">
你只需要做一件事
</div>
<div class="btns">
<button class="primary" @click="state = state + 1">state +1</button>
<button class="secondary" @click="resetAll">重置</button>
<button
class="primary"
@click="state = state + 1"
>
state +1
</button>
<button
class="secondary"
@click="resetAll"
>
重置
</button>
</div>
<div class="hint ok">
State 变了界面三处会自动同步不需要你手动找 DOM 去改
</div>
<div class="mini">
<div class="mini-title">这里的两个新词</div>
<div class="mini-title">
这里的两个新词
</div>
<div class="mini-item">
<strong>DOM</strong>浏览器里的页面结构按钮/文字/图片都在里面
</div>
@@ -8,21 +8,40 @@
:class="{ active: selectedLayer === index }"
@click="selectedLayer = index"
>
<div class="layer-number">{{ index + 1 }}</div>
<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 class="layer-number">
{{ index + 1 }}
</div>
<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 }}
</div>
<div class="layer-icon">{{ layer.icon }}</div>
</div>
</div>
<div class="layer-detail" v-if="selectedLayer !== null">
<div class="detail-title">{{ layers[selectedLayer].name }}</div>
<div class="detail-desc">{{ layers[selectedLayer].description }}</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>
<div class="detail-functions">
<div class="function-title">主要功能</div>
<div class="function-title">
主要功能
</div>
<div class="function-list">
<div
v-for="(func, index) in layers[selectedLayer].functions"
@@ -34,7 +53,9 @@
</div>
</div>
<div class="detail-examples">
<div class="example-title">常见设备</div>
<div class="example-title">
常见设备
</div>
<div class="example-list">
<div
v-for="(device, index) in layers[selectedLayer].devices"
@@ -48,14 +69,27 @@
</div>
<div class="data-flow">
<div class="flow-title">数据封装过程发送</div>
<div class="flow-title">
数据封装过程发送
</div>
<div class="flow-steps">
<div class="flow-step" v-for="(step, index) in 5" :key="index">
<div class="step-label">{{ layers[4 - index].name }}</div>
<div
v-for="(step, index) in 5"
:key="index"
class="flow-step"
>
<div class="step-label">
{{ layers[4 - index].name }}
</div>
<div class="step-box">
<span class="box-label">{{ layers[4 - index].dataUnit }}</span>
</div>
<div class="step-arrow" v-if="index < 4"> 添加头部</div>
<div
v-if="index < 4"
class="step-arrow"
>
添加头部
</div>
</div>
</div>
</div>
@@ -1,7 +1,9 @@
<template>
<div class="network-troubleshooting">
<div class="problem-selector">
<div class="selector-title">选择问题类型</div>
<div class="selector-title">
选择问题类型
</div>
<div class="problem-list">
<button
v-for="(problem, index) in problems"
@@ -16,16 +18,23 @@
</div>
</div>
<div class="solution-panel" v-if="selectedProblem !== null">
<div
v-if="selectedProblem !== null"
class="solution-panel"
>
<div class="solution-header">
<div class="solution-title">{{ problems[selectedProblem].name }}</div>
<div class="solution-title">
{{ problems[selectedProblem].name }}
</div>
<div class="solution-desc">
{{ problems[selectedProblem].description }}
</div>
</div>
<div class="solution-steps">
<div class="steps-title">🔧 解决步骤</div>
<div class="steps-title">
🔧 解决步骤
</div>
<div class="steps-list">
<div
v-for="(step, index) in problems[selectedProblem].steps"
@@ -34,13 +43,22 @@
:class="{ completed: completedSteps.has(index) }"
@click="toggleStep(index)"
>
<div class="step-number">{{ index + 1 }}</div>
<div class="step-number">
{{ index + 1 }}
</div>
<div class="step-content">
<div class="step-action">{{ step.action }}</div>
<div class="step-command" v-if="step.command">
<div class="step-action">
{{ step.action }}
</div>
<div
v-if="step.command"
class="step-command"
>
<code>{{ step.command }}</code>
</div>
<div class="step-explanation">{{ step.explanation }}</div>
<div class="step-explanation">
{{ step.explanation }}
</div>
</div>
<div class="step-check">
{{ completedSteps.has(index) ? '✓' : '○' }}
@@ -50,61 +68,89 @@
</div>
<div class="related-tools">
<div class="tools-title">🛠 相关工具</div>
<div class="tools-title">
🛠 相关工具
</div>
<div class="tools-list">
<div
v-for="(tool, index) in problems[selectedProblem].tools"
:key="index"
class="tool-item"
>
<div class="tool-name">{{ tool.name }}</div>
<div class="tool-usage">{{ tool.usage }}</div>
<div class="tool-name">
{{ tool.name }}
</div>
<div class="tool-usage">
{{ tool.usage }}
</div>
</div>
</div>
</div>
</div>
<div class="common-commands">
<div class="commands-title">📋 常用诊断命令</div>
<div class="commands-title">
📋 常用诊断命令
</div>
<div class="commands-grid">
<div class="command-card" v-for="(cmd, index) in commands" :key="index">
<div class="command-name">{{ cmd.name }}</div>
<div class="command-syntax">{{ cmd.syntax }}</div>
<div class="command-desc">{{ cmd.description }}</div>
<div
v-for="(cmd, index) in commands"
:key="index"
class="command-card"
>
<div class="command-name">
{{ cmd.name }}
</div>
<div class="command-syntax">
{{ cmd.syntax }}
</div>
<div class="command-desc">
{{ cmd.description }}
</div>
</div>
</div>
</div>
<div class="troubleshooting-tips">
<div class="tips-title">💡 故障排查技巧</div>
<div class="tips-title">
💡 故障排查技巧
</div>
<div class="tips-list">
<div class="tip-item">
<div class="tip-number">1</div>
<div class="tip-number">
1
</div>
<div class="tip-content">
<strong>从底层到顶层</strong>
<br />物理层 链路层 网络层 传输层 应用层
<br>物理层 链路层 网络层 传输层 应用层
</div>
</div>
<div class="tip-item">
<div class="tip-number">2</div>
<div class="tip-number">
2
</div>
<div class="tip-content">
<strong>分层排查</strong>
<br />先确定问题发生在哪一层再针对性解决
<br>先确定问题发生在哪一层再针对性解决
</div>
</div>
<div class="tip-item">
<div class="tip-number">3</div>
<div class="tip-number">
3
</div>
<div class="tip-content">
<strong>二分法定位</strong>
<br />
<br>
ping 本机 ping 网关 ping 外网 ping 域名
</div>
</div>
<div class="tip-item">
<div class="tip-number">4</div>
<div class="tip-number">
4
</div>
<div class="tip-content">
<strong>查看日志</strong>
<br />系统日志应用日志防火墙日志记录关键信息
<br>系统日志应用日志防火墙日志记录关键信息
</div>
</div>
</div>
@@ -5,8 +5,12 @@
<template>
<div class="render-demo">
<div class="header">
<div class="title">渲染策略CSR / SSR / SSG</div>
<div class="subtitle">选择策略观察首屏表现</div>
<div class="title">
渲染策略CSR / SSR / SSG
</div>
<div class="subtitle">
选择策略观察首屏表现
</div>
</div>
<div class="options">
@@ -23,20 +27,34 @@
<div class="cards">
<div class="card">
<div class="label">TTFB</div>
<div class="value">{{ metrics.ttfb }} ms</div>
<div class="label">
TTFB
</div>
<div class="value">
{{ metrics.ttfb }} ms
</div>
</div>
<div class="card">
<div class="label">可交互时间</div>
<div class="value">{{ metrics.tti }} ms</div>
<div class="label">
可交互时间
</div>
<div class="value">
{{ metrics.tti }} ms
</div>
</div>
<div class="card">
<div class="label">SEO 友好</div>
<div class="value">{{ metrics.seo }}</div>
<div class="label">
SEO 友好
</div>
<div class="value">
{{ metrics.seo }}
</div>
</div>
</div>
<div class="hint">{{ metrics.note }}</div>
<div class="hint">
{{ metrics.note }}
</div>
</div>
</template>
@@ -5,8 +5,12 @@
<template>
<div class="responsive-demo">
<div class="header">
<div class="title">响应式布局一套代码多种屏幕</div>
<div class="subtitle">拖动宽度观察列数变化</div>
<div class="title">
响应式布局一套代码多种屏幕
</div>
<div class="subtitle">
拖动宽度观察列数变化
</div>
</div>
<div class="controls">
@@ -19,12 +23,24 @@
min="320"
max="1200"
step="10"
/>
>
</div>
<div class="preview" :style="{ width: viewportWidth + 'px' }">
<div class="grid" :style="gridStyle">
<div v-for="n in 6" :key="n" class="card">Card {{ n }}</div>
<div
class="preview"
:style="{ width: viewportWidth + 'px' }"
>
<div
class="grid"
:style="gridStyle"
>
<div
v-for="n in 6"
:key="n"
class="card"
>
Card {{ n }}
</div>
</div>
</div>
@@ -5,8 +5,12 @@
<template>
<div class="routing-demo">
<div class="header">
<div class="title">路由方式整页刷新 vs 局部切换</div>
<div class="subtitle">点击导航感受体验差异</div>
<div class="title">
路由方式整页刷新 vs 局部切换
</div>
<div class="subtitle">
点击导航感受体验差异
</div>
</div>
<div class="mode-switch">
@@ -27,14 +31,26 @@
</div>
<div class="nav">
<button v-for="page in pages" :key="page" @click="navigate(page)">
<button
v-for="page in pages"
:key="page"
@click="navigate(page)"
>
{{ page }}
</button>
</div>
<div class="screen">
<div v-if="loading" class="loading">页面加载中...</div>
<div v-else class="content">
<div
v-if="loading"
class="loading"
>
页面加载中...
</div>
<div
v-else
class="content"
>
当前页面<strong>{{ currentPage }}</strong>
</div>
</div>
@@ -25,11 +25,20 @@
<div class="row">
<span class="label">常见位置</span><span>{{ current.scene }}</span>
</div>
<div class="row code-title">示例</div>
<div class="row code-title">
示例
</div>
<pre><code>{{ current.example }}</code></pre>
<div class="row code-title">渲染效果</div>
<div class="preview-box" v-html="current.example"></div>
<div class="row tip">小贴士{{ current.tip }}</div>
<div class="row code-title">
渲染效果
</div>
<div
class="preview-box"
v-html="current.example"
/>
<div class="row tip">
小贴士{{ current.tip }}
</div>
</div>
</div>
</template>
@@ -5,34 +5,58 @@
<template>
<div class="slice-demo">
<div class="header">
<div class="title">切图时代请求数越多越慢</div>
<div class="subtitle">调整切图数量观察加载时间变化</div>
<div class="title">
切图时代请求数越多越慢
</div>
<div class="subtitle">
调整切图数量观察加载时间变化
</div>
</div>
<div class="controls">
<label>
切图数量<strong>{{ slices }}</strong>
</label>
<input v-model="slices" type="range" min="1" max="30" step="1" />
<input
v-model="slices"
type="range"
min="1"
max="30"
step="1"
>
<label class="toggle">
<input v-model="useSprite" type="checkbox" />
<input
v-model="useSprite"
type="checkbox"
>
合并雪碧图 (Sprite)
</label>
</div>
<div class="metrics">
<div class="metric">
<div class="label">总请求数</div>
<div class="value">{{ totalRequests }}</div>
<div class="label">
总请求数
</div>
<div class="value">
{{ totalRequests }}
</div>
</div>
<div class="metric">
<div class="label">预计加载时间</div>
<div class="value">{{ loadTime }} ms</div>
<div class="label">
预计加载时间
</div>
<div class="value">
{{ loadTime }} ms
</div>
</div>
</div>
<div class="bar">
<div class="progress" :style="{ width: barWidth + '%' }"></div>
<div
class="progress"
:style="{ width: barWidth + '%' }"
/>
</div>
</div>
</template>
@@ -5,7 +5,9 @@
<template>
<div class="spa-state-demo">
<div class="header">
<div class="title">页面切换时输入会不会丢</div>
<div class="title">
页面切换时输入会不会丢
</div>
<div class="subtitle">
同样点击切换页面MPA 会像刷新一样清空SPA 会保留状态
</div>
@@ -26,7 +28,12 @@
>
SPA局部切换
</button>
<button class="reset" @click="resetAll">重置</button>
<button
class="reset"
@click="resetAll"
>
重置
</button>
</div>
<div class="app">
@@ -43,8 +50,16 @@
</div>
<div class="screen">
<div v-if="loading" class="loading">加载中...</div>
<div v-else class="content">
<div
v-if="loading"
class="loading"
>
加载中...
</div>
<div
v-else
class="content"
>
<div class="row">
当前页面<strong>{{ page }}</strong>
</div>
@@ -52,7 +67,11 @@
<div class="form">
<label>
备注模拟表单输入
<input v-model="note" type="text" placeholder="输入点东西试试" />
<input
v-model="note"
type="text"
placeholder="输入点东西试试"
>
</label>
<div class="help">
提示切到别的页面再回来看看这段文字还在不在
@@ -61,23 +80,39 @@
<div class="row">
购物车数量模拟状态
<button class="small" @click="cart = Math.max(0, cart - 1)">
<button
class="small"
@click="cart = Math.max(0, cart - 1)"
>
-
</button>
<strong class="num">{{ cart }}</strong>
<button class="small" @click="cart = cart + 1">+</button>
<button
class="small"
@click="cart = cart + 1"
>
+
</button>
</div>
</div>
</div>
<div class="explain">
<div class="card">
<div class="label">你现在看到的现象</div>
<div class="value">{{ explainText }}</div>
<div class="label">
你现在看到的现象
</div>
<div class="value">
{{ explainText }}
</div>
</div>
<div class="card">
<div class="label">背后的原因一句话</div>
<div class="value">{{ reasonText }}</div>
<div class="label">
背后的原因一句话
</div>
<div class="value">
{{ reasonText }}
</div>
</div>
</div>
</div>
@@ -8,88 +8,158 @@
type="text"
placeholder="例如: 192.168.1.0"
class="ip-input"
/>
>
</div>
<div class="input-group">
<label class="input-label">子网掩码</label>
<select v-model="cidr" class="cidr-select">
<option v-for="n in 32" :key="n" :value="n">/{{ n }}</option>
<select
v-model="cidr"
class="cidr-select"
>
<option
v-for="n in 32"
:key="n"
:value="n"
>
/{{ n }}
</option>
</select>
</div>
<button class="calculate-btn" @click="calculate">计算</button>
<button
class="calculate-btn"
@click="calculate"
>
计算
</button>
</div>
<div class="results" v-if="results">
<div
v-if="results"
class="results"
>
<div class="result-section">
<div class="section-title">基本信息</div>
<div class="section-title">
基本信息
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">网络地址</div>
<div class="result-value">{{ results.network }}</div>
<div class="result-label">
网络地址
</div>
<div class="result-value">
{{ results.network }}
</div>
</div>
<div class="result-item">
<div class="result-label">广播地址</div>
<div class="result-value">{{ results.broadcast }}</div>
<div class="result-label">
广播地址
</div>
<div class="result-value">
{{ results.broadcast }}
</div>
</div>
<div class="result-item">
<div class="result-label">子网掩码</div>
<div class="result-value">{{ results.mask }}</div>
<div class="result-label">
子网掩码
</div>
<div class="result-value">
{{ results.mask }}
</div>
</div>
<div class="result-item">
<div class="result-label">可用主机数</div>
<div class="result-value">{{ results.hosts }}</div>
<div class="result-label">
可用主机数
</div>
<div class="result-value">
{{ results.hosts }}
</div>
</div>
</div>
</div>
<div class="result-section">
<div class="section-title">IP 范围</div>
<div class="section-title">
IP 范围
</div>
<div class="range-display">
<div class="range-item">
<div class="range-label">起始 IP</div>
<div class="range-value">{{ results.firstHost }}</div>
<div class="range-label">
起始 IP
</div>
<div class="range-value">
{{ results.firstHost }}
</div>
</div>
<div class="range-arrow">
</div>
<div class="range-arrow"></div>
<div class="range-item">
<div class="range-label">结束 IP</div>
<div class="range-value">{{ results.lastHost }}</div>
<div class="range-label">
结束 IP
</div>
<div class="range-value">
{{ results.lastHost }}
</div>
</div>
</div>
</div>
<div class="result-section">
<div class="section-title">二进制表示</div>
<div class="section-title">
二进制表示
</div>
<div class="binary-display">
<div class="binary-row">
<div class="binary-label">IP 地址</div>
<div class="binary-value">{{ results.binaryIp }}</div>
<div class="binary-label">
IP 地址
</div>
<div class="binary-value">
{{ results.binaryIp }}
</div>
</div>
<div class="binary-row">
<div class="binary-label">子网掩码</div>
<div class="binary-value">{{ results.binaryMask }}</div>
<div class="binary-label">
子网掩码
</div>
<div class="binary-value">
{{ results.binaryMask }}
</div>
</div>
<div class="binary-row">
<div class="binary-label">网络地址</div>
<div class="binary-value">{{ results.binaryNetwork }}</div>
<div class="binary-label">
网络地址
</div>
<div class="binary-value">
{{ results.binaryNetwork }}
</div>
</div>
</div>
</div>
<div class="result-section">
<div class="section-title">子网类型</div>
<div class="section-title">
子网类型
</div>
<div class="subnet-info">
<div class="info-tag" :class="getSubnetClass(cidr)">
<div
class="info-tag"
:class="getSubnetClass(cidr)"
>
{{ getSubnetType(cidr) }}
</div>
<div class="info-desc">{{ getSubnetDescription(cidr) }}</div>
<div class="info-desc">
{{ getSubnetDescription(cidr) }}
</div>
</div>
</div>
</div>
<div class="example-presets">
<div class="presets-title">常见子网示例</div>
<div class="presets-title">
常见子网示例
</div>
<div class="presets-grid">
<button
v-for="(preset, index) in presets"
@@ -103,7 +173,9 @@
</div>
<div class="info-box">
<div class="info-title">💡 子网划分知识点</div>
<div class="info-title">
💡 子网划分知识点
</div>
<div class="info-content">
<div class="info-item">
<strong>什么是子网</strong>
@@ -115,11 +187,11 @@
</div>
<div class="info-item">
<strong>常用子网掩码</strong>
<br />
<br>
/8 = 255.0.0.0 (A )
<br />
<br>
/16 = 255.255.0.0 (B )
<br />
<br>
/24 = 255.255.255.0 (C )
</div>
</div>
@@ -6,10 +6,20 @@
<span :class="connectionStatus.toLowerCase()">{{ statusText }}</span>
</div>
<div class="buttons">
<button v-if="step === 0" @click="startHandshake" class="action-btn">
<button
v-if="step === 0"
class="action-btn"
@click="startHandshake"
>
{{ t.connect }}
</button>
<button v-else @click="reset" class="reset-btn">{{ t.reset }}</button>
<button
v-else
class="reset-btn"
@click="reset"
>
{{ t.reset }}
</button>
</div>
</div>
@@ -20,9 +30,17 @@
<span class="icon">💻</span>
<span class="name">{{ t.client }}</span>
</div>
<div class="line"></div>
<div class="state-marker" :class="{ active: step >= 1 }">SYN_SENT</div>
<div class="state-marker" :class="{ active: step >= 3 }">
<div class="line" />
<div
class="state-marker"
:class="{ active: step >= 1 }"
>
SYN_SENT
</div>
<div
class="state-marker"
:class="{ active: step >= 3 }"
>
ESTABLISHED
</div>
</div>
@@ -32,9 +50,16 @@
<!-- SYN Packet -->
<div class="packet-track">
<transition name="slide-right">
<div v-if="showSyn" class="packet syn">
<div class="packet-body">SYN</div>
<div class="packet-detail">SEQ=0</div>
<div
v-if="showSyn"
class="packet syn"
>
<div class="packet-body">
SYN
</div>
<div class="packet-detail">
SEQ=0
</div>
</div>
</transition>
</div>
@@ -42,9 +67,16 @@
<!-- SYN-ACK Packet -->
<div class="packet-track reverse">
<transition name="slide-left">
<div v-if="showSynAck" class="packet syn-ack">
<div class="packet-body">SYN-ACK</div>
<div class="packet-detail">SEQ=0, ACK=1</div>
<div
v-if="showSynAck"
class="packet syn-ack"
>
<div class="packet-body">
SYN-ACK
</div>
<div class="packet-detail">
SEQ=0, ACK=1
</div>
</div>
</transition>
</div>
@@ -52,9 +84,16 @@
<!-- ACK Packet -->
<div class="packet-track">
<transition name="slide-right">
<div v-if="showAck" class="packet ack">
<div class="packet-body">ACK</div>
<div class="packet-detail">SEQ=1, ACK=1</div>
<div
v-if="showAck"
class="packet ack"
>
<div class="packet-body">
ACK
</div>
<div class="packet-detail">
SEQ=1, ACK=1
</div>
</div>
</transition>
</div>
@@ -66,9 +105,17 @@
<span class="icon">🖥</span>
<span class="name">{{ t.server }}</span>
</div>
<div class="line"></div>
<div class="state-marker" :class="{ active: step >= 2 }">SYN_RCVD</div>
<div class="state-marker" :class="{ active: step >= 3 }">
<div class="line" />
<div
class="state-marker"
:class="{ active: step >= 2 }"
>
SYN_RCVD
</div>
<div
class="state-marker"
:class="{ active: step >= 3 }"
>
ESTABLISHED
</div>
</div>
@@ -3,40 +3,72 @@
<div class="comparison-grid">
<div class="protocol-card tcp">
<div class="protocol-header">
<div class="protocol-icon">🔒</div>
<div class="protocol-title">TCP</div>
<div class="protocol-subtitle">传输控制协议</div>
<div class="protocol-icon">
🔒
</div>
<div class="protocol-title">
TCP
</div>
<div class="protocol-subtitle">
传输控制协议
</div>
</div>
<div class="protocol-features">
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">可靠传输</div>
<div class="feature-icon">
</div>
<div class="feature-text">
可靠传输
</div>
</div>
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">面向连接</div>
<div class="feature-icon">
</div>
<div class="feature-text">
面向连接
</div>
</div>
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">流量控制</div>
<div class="feature-icon">
</div>
<div class="feature-text">
流量控制
</div>
</div>
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">拥塞控制</div>
<div class="feature-icon">
</div>
<div class="feature-text">
拥塞控制
</div>
</div>
<div class="feature-item bad">
<div class="feature-icon"></div>
<div class="feature-text">速度较慢</div>
<div class="feature-icon">
</div>
<div class="feature-text">
速度较慢
</div>
</div>
<div class="feature-item bad">
<div class="feature-icon"></div>
<div class="feature-text">开销较大</div>
<div class="feature-icon">
</div>
<div class="feature-text">
开销较大
</div>
</div>
</div>
<div class="protocol-example">
<div class="example-title">应用场景</div>
<div class="example-title">
应用场景
</div>
<div class="example-tags">
<span class="tag">网页浏览</span>
<span class="tag">文件传输</span>
@@ -45,22 +77,48 @@
</div>
<div class="handshake-demo">
<div class="demo-title">三次握手</div>
<div class="demo-title">
三次握手
</div>
<div class="handshake-steps">
<div class="step" :class="{ active: tcpStep >= 1 }">
<div class="step-arrow"></div>
<div class="step-text">SYN</div>
<div
class="step"
:class="{ active: tcpStep >= 1 }"
>
<div class="step-arrow">
</div>
<div class="step-text">
SYN
</div>
</div>
<div class="step" :class="{ active: tcpStep >= 2 }">
<div class="step-arrow"></div>
<div class="step-text">SYN-ACK</div>
<div
class="step"
:class="{ active: tcpStep >= 2 }"
>
<div class="step-arrow">
</div>
<div class="step-text">
SYN-ACK
</div>
</div>
<div class="step" :class="{ active: tcpStep >= 3 }">
<div class="step-arrow"></div>
<div class="step-text">ACK</div>
<div
class="step"
:class="{ active: tcpStep >= 3 }"
>
<div class="step-arrow">
</div>
<div class="step-text">
ACK
</div>
</div>
</div>
<button class="demo-btn" @click="startTcpHandshake">
<button
class="demo-btn"
@click="startTcpHandshake"
>
{{ tcpStep === 0 ? '演示握手' : '重新演示' }}
</button>
</div>
@@ -68,40 +126,72 @@
<div class="protocol-card udp">
<div class="protocol-header">
<div class="protocol-icon"></div>
<div class="protocol-title">UDP</div>
<div class="protocol-subtitle">用户数据报协议</div>
<div class="protocol-icon">
</div>
<div class="protocol-title">
UDP
</div>
<div class="protocol-subtitle">
用户数据报协议
</div>
</div>
<div class="protocol-features">
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">快速传输</div>
<div class="feature-icon">
</div>
<div class="feature-text">
快速传输
</div>
</div>
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">开销小</div>
<div class="feature-icon">
</div>
<div class="feature-text">
开销小
</div>
</div>
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">无连接</div>
<div class="feature-icon">
</div>
<div class="feature-text">
无连接
</div>
</div>
<div class="feature-item good">
<div class="feature-icon"></div>
<div class="feature-text">支持多播</div>
<div class="feature-icon">
</div>
<div class="feature-text">
支持多播
</div>
</div>
<div class="feature-item bad">
<div class="feature-icon"></div>
<div class="feature-text">不可靠</div>
<div class="feature-icon">
</div>
<div class="feature-text">
不可靠
</div>
</div>
<div class="feature-item bad">
<div class="feature-icon"></div>
<div class="feature-text">可能丢包</div>
<div class="feature-icon">
</div>
<div class="feature-text">
可能丢包
</div>
</div>
</div>
<div class="protocol-example">
<div class="example-title">应用场景</div>
<div class="example-title">
应用场景
</div>
<div class="example-tags">
<span class="tag">视频直播</span>
<span class="tag">在线游戏</span>
@@ -110,14 +200,23 @@
</div>
<div class="handshake-demo">
<div class="demo-title">直接发送</div>
<div class="demo-title">
直接发送
</div>
<div class="handshake-steps">
<div class="step direct">
<div class="step-arrow"></div>
<div class="step-text">直接发送数据</div>
<div class="step-arrow">
</div>
<div class="step-text">
直接发送数据
</div>
</div>
</div>
<button class="demo-btn" @click="sendUdpData">
<button
class="demo-btn"
@click="sendUdpData"
>
{{ udpSent ? '再发一次' : '发送数据' }}
</button>
</div>
@@ -169,37 +268,55 @@
</div>
<div class="real-world-example">
<div class="example-title">🎬 实际应用示例</div>
<div class="example-title">
🎬 实际应用示例
</div>
<div class="scenario-grid">
<div class="scenario">
<div class="scenario-icon">📺</div>
<div class="scenario-name">视频直播</div>
<div class="scenario-icon">
📺
</div>
<div class="scenario-name">
视频直播
</div>
<div class="scenario-desc">
使用 <strong>UDP</strong>因为 <br /> 丢几帧没关系关键是实时
<br /> 重传会造成延迟和卡顿
使用 <strong>UDP</strong>因为 <br> 丢几帧没关系关键是实时
<br> 重传会造成延迟和卡顿
</div>
</div>
<div class="scenario">
<div class="scenario-icon">🌐</div>
<div class="scenario-name">网页浏览</div>
<div class="scenario-icon">
🌐
</div>
<div class="scenario-name">
网页浏览
</div>
<div class="scenario-desc">
使用 <strong>TCP</strong>因为 <br /> 内容必须完整准确 <br />
使用 <strong>TCP</strong>因为 <br> 内容必须完整准确 <br>
丢失任何数据都不可接受
</div>
</div>
<div class="scenario">
<div class="scenario-icon">🎮</div>
<div class="scenario-name">在线游戏</div>
<div class="scenario-icon">
🎮
</div>
<div class="scenario-name">
在线游戏
</div>
<div class="scenario-desc">
使用 <strong>UDP</strong>因为 <br /> 响应速度比准确更重要
<br /> 实时同步玩家位置
使用 <strong>UDP</strong>因为 <br> 响应速度比准确更重要
<br> 实时同步玩家位置
</div>
</div>
<div class="scenario">
<div class="scenario-icon">📧</div>
<div class="scenario-name">邮件发送</div>
<div class="scenario-icon">
📧
</div>
<div class="scenario-name">
邮件发送
</div>
<div class="scenario-desc">
使用 <strong>TCP</strong>因为 <br /> 邮件内容不能丢失 <br />
使用 <strong>TCP</strong>因为 <br> 邮件内容不能丢失 <br>
可靠性是第一要务
</div>
</div>
@@ -9,53 +9,50 @@
<div class="omnibox">
<span class="lock-icon">🔒</span>
<!-- Segmented URL Display -->
<div class="segmented-url" v-if="parsedUrl">
<div
v-if="parsedUrl"
class="segmented-url"
>
<span
class="url-part protocol"
:class="{ active: highlightedPart === 'protocol' }"
@mouseover="highlightedPart = 'protocol'"
@mouseleave="highlightedPart = null"
>{{ parts.protocol }}:</span
>
>{{ parts.protocol }}:</span>
<span class="divider">//</span>
<span
class="url-part host"
:class="{ active: highlightedPart === 'host' }"
@mouseover="highlightedPart = 'host'"
@mouseleave="highlightedPart = null"
>{{ parts.host }}</span
>
>{{ parts.host }}</span>
<span
v-if="parts.port"
class="url-part port"
:class="{ active: highlightedPart === 'port' }"
@mouseover="highlightedPart = 'port'"
@mouseleave="highlightedPart = null"
>:{{ parts.port }}</span
>
>:{{ parts.port }}</span>
<span
class="url-part pathname"
:class="{ active: highlightedPart === 'pathname' }"
@mouseover="highlightedPart = 'pathname'"
@mouseleave="highlightedPart = null"
>{{ parts.pathname }}</span
>
>{{ parts.pathname }}</span>
<span
v-if="parts.search"
class="url-part search"
:class="{ active: highlightedPart === 'search' }"
@mouseover="highlightedPart = 'search'"
@mouseleave="highlightedPart = null"
>{{ parts.search }}</span
>
>{{ parts.search }}</span>
<span
v-if="parts.hash"
class="url-part hash"
:class="{ active: highlightedPart === 'hash' }"
@mouseover="highlightedPart = 'hash'"
@mouseleave="highlightedPart = null"
>{{ parts.hash }}</span
>
>{{ parts.hash }}</span>
</div>
<input
v-else
@@ -63,12 +60,15 @@
type="text"
class="url-input"
placeholder="https://example.com"
/>
>
</div>
</div>
<div class="visualization-area">
<div v-if="parsedUrl" class="url-breakdown">
<div
v-if="parsedUrl"
class="url-breakdown"
>
<div
v-for="(part, key) in parts"
:key="key"
@@ -81,11 +81,20 @@
<span class="segment-icon">{{ icons[key] }}</span>
<span class="segment-label">{{ labels[key] }}</span>
</div>
<div class="segment-value">{{ part || '-' }}</div>
<div class="segment-desc">{{ descriptions[key] }}</div>
<div class="segment-value">
{{ part || '-' }}
</div>
<div class="segment-desc">
{{ descriptions[key] }}
</div>
</div>
</div>
<div v-else class="error-state">Invalid URL format / 无效的 URL 格式</div>
<div
v-else
class="error-state"
>
Invalid URL format / 无效的 URL 格式
</div>
</div>
</div>
</template>
@@ -20,7 +20,7 @@
<div
class="line-fill"
:style="{ width: (currentStage / (stages.length - 1)) * 100 + '%' }"
></div>
/>
</div>
</div>
@@ -31,13 +31,27 @@
</div>
<div class="component-wrapper">
<transition name="fade" mode="out-in">
<component :is="stages[currentStage].component" :key="currentStage" />
<transition
name="fade"
mode="out-in"
>
<component
:is="stages[currentStage].component"
:key="currentStage"
/>
</transition>
</div>
<div class="action-footer" v-if="currentStage < stages.length - 1">
<button class="next-btn" @click="nextStage">下一步 </button>
<div
v-if="currentStage < stages.length - 1"
class="action-footer"
>
<button
class="next-btn"
@click="nextStage"
>
下一步
</button>
</div>
</div>
</div>
@@ -5,7 +5,9 @@
<template>
<div class="vr-demo">
<div class="header">
<div class="title">Vue vs React它们哪里像哪里不一样</div>
<div class="title">
Vue vs React它们哪里像哪里不一样
</div>
<div class="subtitle">
选一个标签页然后点+1看看背后发生了什么示意
</div>
@@ -25,36 +27,56 @@
<div class="grid">
<div class="panel">
<div class="panel-title">Vue</div>
<div class="panel-title">
Vue
</div>
<div class="preview">
<div class="row">
count: <strong>{{ count }}</strong>
</div>
<button class="btn vue" @click="inc('vue')">+1</button>
<button
class="btn vue"
@click="inc('vue')"
>
+1
</button>
</div>
<div class="code">
<div class="code-title">典型写法示意</div>
<div class="code-title">
典型写法示意
</div>
<pre><code class="language-vue">{{ vueCode }}</code></pre>
</div>
</div>
<div class="panel">
<div class="panel-title">React</div>
<div class="panel-title">
React
</div>
<div class="preview">
<div class="row">
count: <strong>{{ count }}</strong>
</div>
<button class="btn react" @click="inc('react')">+1</button>
<button
class="btn react"
@click="inc('react')"
>
+1
</button>
</div>
<div class="code">
<div class="code-title">典型写法示意</div>
<div class="code-title">
典型写法示意
</div>
<pre><code class="language-jsx">{{ reactCode }}</code></pre>
</div>
</div>
</div>
<div class="what">
<div class="what-title">点击 +1 时发生了什么</div>
<div class="what-title">
点击 +1 时发生了什么
</div>
<div class="steps">
<div
v-for="(s, idx) in steps"
@@ -19,14 +19,29 @@
</button>
</div>
<div class="preview" :class="current">
<h1 class="hero" :class="{ selected: selectedPart === 'h1' }" @click="selectedPart = 'h1'">
<div
class="preview"
:class="current"
>
<h1
class="hero"
:class="{ selected: selectedPart === 'h1' }"
@click="selectedPart = 'h1'"
>
<span class="badge"></span>欢迎来到我的网站
</h1>
<p class="desc" :class="{ selected: selectedPart === 'p' }" @click="selectedPart = 'p'">
<p
class="desc"
:class="{ selected: selectedPart === 'p' }"
@click="selectedPart = 'p'"
>
<span class="badge"></span>这是一段描述文字
</p>
<button class="cta" :class="{ selected: selectedPart === 'btn' }" @click="handleBtnClick">
<button
class="cta"
:class="{ selected: selectedPart === 'btn' }"
@click="handleBtnClick"
>
<span class="badge"></span>点我试试 ({{ clicks }})
</button>
</div>
@@ -34,18 +49,31 @@
<div class="right-panel">
<div class="code-section">
<div class="code-label">{{ codeTitle }}</div>
<div class="code-label">
{{ codeTitle }}
</div>
<div class="code-block">
<div v-for="(line, i) in codeLines" :key="i" :class="['line', { hl: line.key === selectedPart }]">
<div
v-for="(line, i) in codeLines"
:key="i"
:class="['line', { hl: line.key === selectedPart }]"
>
{{ line.text }}
</div>
</div>
</div>
<div class="explain-section">
<div class="explain-label">执行过程</div>
<div class="explain-label">
执行过程
</div>
<ol class="steps">
<li v-for="s in steps" :key="s">{{ s }}</li>
<li
v-for="s in steps"
:key="s"
>
{{ s }}
</li>
</ol>
</div>
</div>