Files
sanbuphy dc8b5773f1 feat: update documentation and component demos for backend layered architecture
- Add new LanguageScopeDemo component for backend languages overview
- Refactor and simplify existing demo components (ControllerLayerDemo, DtoFlowDemo, DependencyDirectionDemo)
- Update .gitignore to exclude .claude/skills directory
- Modify backend-related sections in documentation from "后端与全栈" to "后端开发"
- Add new backend layered architecture demo components (CleanArchitectureDemo, DependencyDirectionDemo)
- Improve documentation structure and content for stage-3 core skills
- Fix component initialization timing in CompileVsInterpretDemo and RateLimiterDemo
- Add design style prompt reference in frontend documentation
2026-03-01 12:28:47 +08:00

165 lines
5.9 KiB
Vue
Raw Permalink 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="compile-vs-interpret-demo">
<h4>🔄 编译型 vs 解释型 vs JIT</h4>
<p class="desc">点击不同执行模式观察代码从源码到运行的过程</p>
<div class="mode-selector">
<button
v-for="(m, i) in modes"
:key="i"
:class="['mode-btn', { active: selected === i }]"
@click="selectMode(i)"
>
{{ m.name }}
</button>
</div>
<div class="pipeline">
<div
v-for="(step, j) in modes[selected].steps"
:key="j"
:class="['pipe-step', { visible: visibleSteps > j }]"
>
<div class="step-icon">{{ step.icon }}</div>
<div class="step-content">
<div class="step-name">{{ step.name }}</div>
<div class="step-desc">{{ step.desc }}</div>
</div>
<div v-if="j < modes[selected].steps.length - 1" class="arrow"></div>
</div>
</div>
<div class="metrics">
<div class="metric" v-for="m in modes[selected].metrics" :key="m.label">
<span class="metric-label">{{ m.label }}</span>
<div class="metric-bar-bg">
<div class="metric-bar" :style="{ width: m.value + '%', background: m.color }"></div>
</div>
<span class="metric-val">{{ m.text }}</span>
</div>
</div>
<div class="examples">
<span class="ex-label">代表语言</span>
<span class="ex-lang" v-for="l in modes[selected].langs" :key="l">{{ l }}</span>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const selected = ref(0)
const visibleSteps = ref(0)
let timer = null
onMounted(() => {
// 组件挂载后开始动画,避免模块加载时启动定时器导致 build 卡住
selectMode(0)
})
onUnmounted(() => {
if (timer) clearInterval(timer)
})
function selectMode(i) {
selected.value = i
visibleSteps.value = 0
clearInterval(timer)
timer = setInterval(() => {
if (visibleSteps.value < modes[i].steps.length) {
visibleSteps.value++
} else {
clearInterval(timer)
}
}, 300)
}
const modes = [
{
name: '编译型',
steps: [
{ icon: '📝', name: '源代码', desc: 'main.c' },
{ icon: '⚙️', name: '编译器', desc: '全量编译' },
{ icon: '📦', name: '机器码', desc: '二进制可执行文件' },
{ icon: '🚀', name: '直接执行', desc: 'CPU 直接运行' }
],
metrics: [
{ label: '运行速度', value: 95, text: '极快', color: '#22c55e' },
{ label: '启动速度', value: 30, text: '慢(需编译)', color: '#ef4444' },
{ label: '跨平台', value: 20, text: '需重新编译', color: '#ef4444' }
],
langs: ['C', 'C++', 'Rust', 'Go']
},
{
name: '解释型',
steps: [
{ icon: '📝', name: '源代码', desc: 'app.py' },
{ icon: '🔍', name: '解释器', desc: '逐行读取' },
{ icon: '🔄', name: '逐行执行', desc: '边翻译边运行' }
],
metrics: [
{ label: '运行速度', value: 30, text: '较慢', color: '#ef4444' },
{ label: '启动速度', value: 90, text: '快(直接运行)', color: '#22c55e' },
{ label: '跨平台', value: 90, text: '天然跨平台', color: '#22c55e' }
],
langs: ['Python', 'Ruby', 'PHP', 'Bash']
},
{
name: 'JIT 即时编译',
steps: [
{ icon: '📝', name: '源代码', desc: 'app.js' },
{ icon: '🔍', name: '解释执行', desc: '先解释运行' },
{ icon: '🔥', name: '热点检测', desc: '发现高频代码' },
{ icon: '⚡', name: 'JIT 编译', desc: '编译为机器码' },
{ icon: '🚀', name: '高速执行', desc: '接近原生速度' }
],
metrics: [
{ label: '运行速度', value: 75, text: '快(热点接近原生)', color: '#22c55e' },
{ label: '启动速度', value: 60, text: '中等(需预热)', color: '#eab308' },
{ label: '跨平台', value: 85, text: '跨平台', color: '#22c55e' }
],
langs: ['JavaScript (V8)', 'Java (JVM)', 'C# (.NET)']
}
]
</script>
<style scoped>
.compile-vs-interpret-demo {
padding: 20px; border: 1px solid var(--vp-c-divider);
border-radius: 12px; margin: 16px 0; background: var(--vp-c-bg-soft);
}
h4 { margin: 0 0 4px; }
.desc { color: var(--vp-c-text-2); font-size: 14px; margin: 0 0 16px; }
.mode-selector { display: flex; gap: 8px; margin-bottom: 16px; }
.mode-btn {
padding: 8px 18px; border-radius: 8px; border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg); cursor: pointer; font-size: 14px; font-weight: 500;
transition: all 0.2s;
}
.mode-btn.active { background: var(--vp-c-brand-1); color: #fff; border-color: var(--vp-c-brand-1); }
.pipeline { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-bottom: 16px; }
.pipe-step {
display: flex; align-items: center; gap: 4px; opacity: 0;
transform: translateY(8px); transition: all 0.3s;
}
.pipe-step.visible { opacity: 1; transform: translateY(0); }
.step-icon { font-size: 24px; }
.step-name { font-size: 12px; font-weight: 600; }
.step-desc { font-size: 11px; color: var(--vp-c-text-3); }
.arrow { color: var(--vp-c-text-3); font-size: 18px; margin: 0 4px; }
.metrics { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.metric { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.metric-label { width: 70px; text-align: right; color: var(--vp-c-text-2); }
.metric-bar-bg { flex: 1; height: 10px; background: var(--vp-c-divider); border-radius: 5px; overflow: hidden; }
.metric-bar { height: 100%; border-radius: 5px; transition: width 0.5s; }
.metric-val { width: 130px; font-size: 12px; color: var(--vp-c-text-3); }
.examples { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ex-label { font-size: 13px; color: var(--vp-c-text-2); }
.ex-lang {
padding: 3px 10px; background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider);
border-radius: 4px; font-size: 12px;
}
@media (max-width: 640px) { .metric-val { width: auto; } }
</style>