2026-02-06 03:34:50 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="dependency-graph-demo">
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<div class="demo-header">
|
|
|
|
|
|
<span class="icon">🕸️</span>
|
|
|
|
|
|
<span class="title">依赖图谱</span>
|
|
|
|
|
|
<span class="subtitle">模块依赖关系可视化</span>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<div class="graph-container">
|
|
|
|
|
|
<svg class="graph-svg" viewBox="0 0 500 300">
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<defs>
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<marker id="arrow" markerWidth="8" markerHeight="6" refX="18" refY="3" orient="auto">
|
|
|
|
|
|
<polygon points="0 0, 8 3, 0 6" fill="var(--vp-c-text-3)" />
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</marker>
|
|
|
|
|
|
</defs>
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<line v-for="edge in edges" :key="edge.id"
|
|
|
|
|
|
:x1="getNode(edge.source).x" :y1="getNode(edge.source).y"
|
|
|
|
|
|
:x2="getNode(edge.target).x" :y2="getNode(edge.target).y"
|
|
|
|
|
|
stroke="var(--vp-c-text-3)" stroke-width="1.5" marker-end="url(#arrow)"
|
|
|
|
|
|
/>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<g v-for="node in nodes" :key="node.id" :transform="`translate(${node.x}, ${node.y})`">
|
|
|
|
|
|
<circle :r="node.r" :fill="node.color" stroke="white" stroke-width="2" />
|
|
|
|
|
|
<text y="4" text-anchor="middle" fill="white" font-size="12">{{ node.icon }}</text>
|
|
|
|
|
|
<text :y="node.r + 14" text-anchor="middle" fill="var(--vp-c-text-1)" font-size="10">{{ node.name }}</text>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</g>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<div class="legend">
|
|
|
|
|
|
<div class="legend-item"><span class="dot entry"></span>入口文件</div>
|
|
|
|
|
|
<div class="legend-item"><span class="dot module"></span>模块</div>
|
|
|
|
|
|
<div class="legend-item"><span class="arrow">→</span>依赖关系</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="info-box">
|
2026-02-13 00:36:06 +08:00
|
|
|
|
<span class="icon">💡</span>
|
|
|
|
|
|
<strong>依赖图谱的作用:</strong>就像地图一样,帮助你理解模块之间是如何相互引用的。main.js 引用了 utils、components、api,而 components 又引用了 utils——这就是依赖链。
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2026-02-13 00:36:06 +08:00
|
|
|
|
import { ref } from 'vue'
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
|
|
|
|
|
const nodes = ref([
|
2026-02-13 00:36:06 +08:00
|
|
|
|
{ id: 'main', name: 'main.js', icon: '🚀', color: '#646cff', r: 22, x: 250, y: 60 },
|
|
|
|
|
|
{ id: 'utils', name: 'utils.js', icon: '🛠️', color: '#ff6b6b', r: 18, x: 100, y: 150 },
|
|
|
|
|
|
{ id: 'components', name: 'components/', icon: '🧩', color: '#4ecdc4', r: 20, x: 250, y: 150 },
|
|
|
|
|
|
{ id: 'api', name: 'api.js', icon: '🔌', color: '#ffe66d', r: 18, x: 400, y: 150 },
|
|
|
|
|
|
{ id: 'hooks', name: 'hooks.js', icon: '⚓', color: '#ff8b94', r: 16, x: 180, y: 240 },
|
|
|
|
|
|
{ id: 'config', name: 'config.js', icon: '⚙️', color: '#c7ceea', r: 14, x: 320, y: 240 }
|
2026-02-06 03:34:50 +08:00
|
|
|
|
])
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
const edges = ref([
|
|
|
|
|
|
{ id: 1, source: 'main', target: 'utils' },
|
|
|
|
|
|
{ id: 2, source: 'main', target: 'components' },
|
|
|
|
|
|
{ id: 3, source: 'main', target: 'api' },
|
|
|
|
|
|
{ id: 4, source: 'components', target: 'utils' },
|
|
|
|
|
|
{ id: 5, source: 'components', target: 'hooks' },
|
|
|
|
|
|
{ id: 6, source: 'api', target: 'config' }
|
|
|
|
|
|
])
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
|
|
|
|
|
const getNode = (id) => nodes.value.find(n => n.id === id)
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.dependency-graph-demo {
|
|
|
|
|
|
border: 1px solid var(--vp-c-divider);
|
2026-02-14 20:23:34 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-13 00:36:06 +08:00
|
|
|
|
background: var(--vp-c-bg-soft);
|
2026-02-14 20:23:34 +08:00
|
|
|
|
padding: 0.75rem;
|
|
|
|
|
|
margin: 0.5rem 0;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.demo-header {
|
2026-02-06 03:34:50 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 0.5rem;
|
2026-02-13 00:36:06 +08:00
|
|
|
|
margin-bottom: 1rem;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.demo-header .icon { font-size: 1.25rem; }
|
|
|
|
|
|
.demo-header .title { font-weight: bold; font-size: 1rem; }
|
|
|
|
|
|
.demo-header .subtitle { color: var(--vp-c-text-2); font-size: 0.85rem; margin-left: 0.5rem; }
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
|
|
|
|
|
.graph-container {
|
|
|
|
|
|
background: var(--vp-c-bg);
|
2026-02-13 00:36:06 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
border: 1px solid var(--vp-c-divider);
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.graph-svg {
|
|
|
|
|
|
width: 100%;
|
2026-02-13 00:36:06 +08:00
|
|
|
|
height: auto;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.legend {
|
2026-02-06 03:34:50 +08:00
|
|
|
|
display: flex;
|
2026-02-13 00:36:06 +08:00
|
|
|
|
gap: 1.5rem;
|
|
|
|
|
|
margin-top: 0.75rem;
|
|
|
|
|
|
font-size: 0.8rem;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
color: var(--vp-c-text-2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.legend-item { display: flex; align-items: center; gap: 0.3rem; }
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.dot {
|
|
|
|
|
|
width: 10px;
|
|
|
|
|
|
height: 10px;
|
|
|
|
|
|
border-radius: 50%;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.dot.entry { background: #646cff; }
|
|
|
|
|
|
.dot.module { background: #4ecdc4; }
|
|
|
|
|
|
.arrow { color: var(--vp-c-text-3); }
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
|
|
|
|
|
.info-box {
|
2026-02-13 00:36:06 +08:00
|
|
|
|
background: var(--vp-c-bg-alt);
|
2026-02-06 03:34:50 +08:00
|
|
|
|
padding: 0.75rem;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
font-size: 0.85rem;
|
|
|
|
|
|
color: var(--vp-c-text-2);
|
2026-02-13 00:36:06 +08:00
|
|
|
|
margin-top: 0.75rem;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-13 00:36:06 +08:00
|
|
|
|
.info-box .icon { margin-right: 0.25rem; }
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</style>
|