递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
vue scoped css 隔离由编译阶段注入 data-v-hash 属性与 css 选择器重写共同实现,vnode 仅携带该属性而不参与作用域逻辑,实际隔离依赖浏览器 css 引擎匹配。

Vue 的 Scoped CSS 不是靠运行时逻辑控制的,而是编译阶段就定下来的“属性绑定 + 选择器改写”配合浏览器原生 CSS 匹配能力实现的。
编译时给元素加唯一标识
当组件用了 <style scoped></style>,Vue 的编译器(比如 vue/compiler-sfc 或 vue-loader)会为模板中大多数 HTML 元素自动添加一个形如 data-v-f3f264d4 的属性:
- 这个哈希值(如
f3f264d4)通常基于组件文件路径或内容生成,保证每个组件唯一 - 普通标签(
<div>、<code><p></p>、<span></span>等)都会被加上该属性 - 子组件根节点默认也会被注入(但它的内部元素不会带父组件的
data-v-xxx) -
v-html内容、<slot></slot>插槽内容默认不加,除非显式配置 -
.btn { color: red; }→ 编译成.btn[data-v-f3f264d4] { color: red; } - 深层穿透写法如
::v-deep .icon或:deep(.icon)→ 编译成[data-v-f3f264d4] .icon(不强制要求 .icon 元素自身带该属性) - 这种重写纯属构建时行为,输出的 CSS 已固化,和运行时无关
- 它如实携带编译器注入的
data-v-xxx属性(例如vnode.props['data-v-f3f264d4'] = '') - 挂载时把这些属性写入真实 DOM 节点
- 真正起作用的是浏览器:只有同时满足“类名匹配”且“存在对应
data-v-xxx属性”的元素,才会被应用该样式 - 子组件 DOM 默认没有父组件的
data-v-xxx,所以父组件的 scoped 样式自然穿不透 - scopedId 的生成、属性注入、选择器重写,全部发生在构建阶段
- VNode 是纯数据结构,不理解
data-v-xxx的语义,也不参与样式逻辑 - 没有“作用域检查中间件”,没有 runtime 的 scope 对比或拦截
- 调试时在浏览器里看到的
data-v-xxx和对应 CSS 规则,就是最终生效的全部依据
同时重写 CSS 选择器
对应地,<style scoped></style> 中的样式规则会被 PostCSS 插件(如 postcss-plugin-scoped)处理:
运行时只负责渲染,隔离靠浏览器
VNode 在这里只是“搬运工”:
注意几个关键事实
Scoped 隔离不依赖 VNode 的运行时判断,也不做动态校验:










