管什么:
10-media十篇里的近义媒体组件怎么选、这一层的坑谁踩过、动之前先读哪几篇。不管什么:浮层基座本身(A07)、层级账本机制(I10)、Design Token 框架(A03)、语言包体系(I11)。这几处本篇只引不证,指向被引篇。
10-media 的八个组件没有一个是「纯 DOM 装配」,它们各自带一块不在 Vue 渲染体系里的产物或算法。所以进这一类要回答的第一个问题不是「用哪个组件」,而是「这块产物由谁生成、由谁负责」。状态因此分成两种流向:图片与走马灯持的是「当前是哪一张」的索引位,落在注册表或厂商层实例字段上(C10-00 论点 2、C10-04 论点 4);水印、二维码、头像、图表持的是「一次绘制产物」,写入时机在挂载之后的副作用里(C10-06 取舍三、C10-05 论点 2)。
浮层模型在本类有三套且互不复用。图片预览把容器、层级、Esc、滚动锁、焦点整包外包给库内 Dialog,Preview 全文不写一个 zIndex(C10-00 论点 1);画廊自己搭 Portal 加手工层级,代价是库内多出一套滚动锁、一套 Esc 通路、一套焦点策略(C10-00 取舍四);对比与走马灯压根没有浮层(C10-00 论点 6)。在 Image 组与 Gallery 之间选,本质是在选这两套浮层,而不是比功能清单。
「现在这张是谁」的所有权在两个组件里给出两种答案,不能直接对照。图片组用自增整数 key 配 Map 的插入序(C10-00 论点 2),换来的是增删不跟丢,赔上的是改 src 会把这张图挪到表尾(C10-01 论点 3);走马灯的状态住在厂商层实例字段,靠一个假 prop 冒充「props 变了」(C10-04 论点 4)。跨组件同步索引前先确认自己面对的是哪个坐标系(C10-01 坑 3、C10-04 坑 7)。
加载、失败与兜底链的完整度同样参差。只有单图壳有 loading、error、骨架三态,预览层对图片是否加载成功毫不知情(C10-00 论点 3);头像把同一件事压成一个 isImgExist 位、复位只挂在 src 上(C10-05 论点 1);水印与二维码在挂载后异步取图,各自的失败分支一处有一处没有(C10-06 论点 6、C10-07 论点 6)。
内核来源是本类最该记住的差异,也是下面选型表里「而不是另一个」那一列的根据:水印是本仓 Canvas 2D 自绘加 toDataURL,没有第三方内核(C10-06 取舍四);二维码是 vendored 的 qrcodegen 单文件源码副本,业务层只消费一条调用链(C10-07 取舍一);走马灯是逐字平移上游的 vc-slick,整层不在类型检查覆盖内(C10-04 取舍二);图表是本类里唯一把渲染交给 npm 运行时依赖的组件,而本层与引擎之间没有映射层(C10-08 论点 1);预览层复用库内 Dialog(C10-00 取舍一);头像、评论没有内核。富内容的解析与渲染不在本类,也不再有库内编辑器可指(原编辑类组件已于 2026-10-02 移除):评论只提供六个槽(C10-09 论点 2),标记语言的解析与出口净化由调用方自备。
结论是:这一层在把「画什么、生成什么」交出去的同时,也把抗篡改强度、许可证义务、静态样式抽取、主题治理与注入面一并交了出去(C10-06 取舍一、C10-07 取舍一、C10-08 论点 1)。下面两张表分别回答「该选哪一个」与「这个症状谁踩过」;机制论证在被引的那一篇里,本篇不重述。
| 要解决的问题 | 选它 | 而不是另一个 | 判据 |
|---|---|---|---|
| 一组图,点任意一张进全屏并可左右切换 | C10-01 image 的 PreviewGroup | 给图片组外面自套一层 Dialog | 图片组的注册表用自增 key,v-for 增删与异步插入都不会跟丢当前项(C10-00 论点 2);预览浮层复用 vc-dialog,层级交给样式表,JS 侧零 zIndex 字样(C10-00 论点 1) |
| 两张图同位叠加,拖一条分界线比差异 | C10-02 image-compare | C10-04 carousel 放两张 | 对比只有一个 CSS 变量加一条裁剪规则,拖动不触发重渲染之外的工作(C10-02 取舍 2);走马灯是轨道位移模型,没有同位叠加语义(C10-00 论点 6) |
| 多张同屏、自动轮播、淡入淡出、响应式切片数 | C10-04 carousel | C10-01 image 的 PreviewGroup | 走马灯的自动播放是实例字段上的五态状态机,「为什么暂停」被显式建模(C10-04 论点 2 与 取舍三);图片组只管预览态的切换,没有轮播与自动播放的概念 |
| 一个用户标识小块,文字长就要整体等比缩 | C10-05 avatar | C10-01 image 的缩略形态 | 头像的回退链是单个布尔位且复位只挂 src(C10-05 论点 1),缩放必须 JS 量 offsetWidth(C10-05 论点 2);图片侧的三态只存在于单图壳(C10-00 论点 3) |
| 在一段内容上盖一层抗截图、抗删改的标识 | C10-06 watermark | 绝对定位一张半透明 PNG | 水印层是不进样式链路的无类名裸节点,靠查不到选择器来免疫 CSS 篡改(C10-06 论点 1),复原由记录驱动的观察器负责(C10-06 取舍二) |
| 把一段文本换成可扫描的图形并带状态遮罩 | C10-07 qrcode | 自己再引一个二维码 npm 包 | 内核已是 vendored 单文件副本,仓内读者只有本组件(C10-07 取舍一);介质在两种实现间二选一,而实例引用只挂在其中一侧(C10-07 论点 2) |
| 画一张可交互、可导出的数据图 | C10-08 chart | 用 C10-07 qrcode 那类自绘介质 | 本层与引擎之间只有四个键的字面搬运,不在四键里的公开 props 永远到不了引擎(C10-08 论点 1),更新通道只有销毁重建(C10-08 论点 2) |
| 展示一条带作者、头像、时间与操作项的用户内容 | C10-09 comment | 用列表组件自己拼四段 | 评论不 import 头像,字符串形态的 avatar 退化成没有回退的裸 img(C10-09 论点 1),嵌套不做递归组件、层级外推给调用方(C10-09 取舍三) |
| 正文需要富内容(Markdown、HTML、代码高亮) | 类外:自备解析与渲染(编辑器组件已于 2026-10-02 移除),C11-08 typography 管行内 | C10-09 comment | 评论六个槽里只有 default 经过归一化,空槽会渲染出空壳(C10-09 论点 2);它不解析任何标记语言,注入面归调用方自己 |
A. 写在标签上的东西整批丢了(attrs 与外框样式一族)
inheritAttrs: false 之后 id、data-*、@mouseenter 静默消失 → C10-08 论点 4(声明了却从不接 attrs)。class 落不上而 style 只部分存活 → C10-07 坑 4,背景色被组件给的 transparent 顶掉;反面教训是水印,它的 style 生效过头,一句 position: static 就把定位基座撤走、水印跑出容器 → C10-06 坑 2。C10-02 坑 4(比例与溢出写死在根规则里,外部 style 一改就错位);二维码更彻底,prefixCls 没声明,前缀只能上全局配置(C10-07 §五)。B. 传了参数却什么都不发生(API 面存活、实现死亡)
C10-07 坑 3(转译通道里没有这个键)、C10-04 坑 4(厂商层没有读取点)、C10-04 坑 3(prop 形态的自定义箭头)、C10-05 坑 5(组下发的响应式尺寸)、C10-09 坑 3(操作项用 prop 数组就吃不到交互样式)。成因分两种:键名改写表见 C10-07 论点 3,两层 props 差集无校验见 C10-04 论点 5。C10-01 坑 6(组上写 preview={false} 整组照旧可预览);同族是头像组用带默认值的 shape 吃掉子件显式值(C10-05 论点 3)与 Spin 的 size(C11-01 坑 2)。C10-02 坑 1(合成的 disabled 没被解构,三处直读 props.disabled);行外同族判据见 C11-08 坑 1。C. 「当前是哪一张」错位(受控、下标与顺序)
C10-01 坑 3(未过滤表与已过滤表两套坐标系)。C10-00 坑 4。C10-01 坑 4,根因是退登再注册把 key 挪到表尾(C10-00 坑 3)。afterChange 的索引少一张 → C10-04 坑 7,由一个没写进文档的 attr 触发;v-for 切片的 :key 被位置序无条件替换 → C10-04 坑 5。D. 加载、失败与兜底链的反直觉
C10-01 坑 1;同一条死 watcher 在 C10-00 坑 6。fallback 生效后这张图从切换序列里消失,且再也发不出第二次错误 → C10-01 坑 2 与 C10-00 坑 5。注意「预览里会看到那张坏图」这个说法不成立,错误态下预览层根本不渲染,此断言已由 C10-01 论点 2 定稿。srcset 不重试 → C10-05 坑 6;无布局环境下文字缩放恒不生效 → C10-05 论点 2;挂载被打断则文字恒 opacity: 0 → C10-05 坑 4。C10-07 论点 6 与 C10-07 坑 5;水印图片模式的复原只挂在 onload 上,图源失败就永远回不来 → C10-06 坑 4;图表引擎构造失败照样发事件、载荷是空值 → C10-08 论点 6。E. 浮层、层级与全局锁
C10-00 坑 7;框架侧根因是回收按「元素此刻的行内值」记账而不是按身份(I10 论点 4),三套账本互不知情见 A07 论点 7。C10-04 坑 1,这把 window 级锁不保存原值且天然跨实例(C10-04 论点 3)。F. 主题与样式治理脱离
C10-09 论点 4 与 C10-09 坑 5;框架机制见 A03 论点 4,而「按形参名搜判据」这个错法由 C10-09 论点 4 自己更正(要数实参个数)。C10-07 取舍五;水印则整层不产 CSS,静态样式抽取对它零覆盖 → C10-06 取舍一。C04-03 论点 6;本类的正例写法在 C10-05 论点 5。C10-04 论点 7;类型里有、mergeToken 从不赋值的死 token → C10-05 坑 7。C10-09 坑 6(那个字面量是手工副本);正文用段落标签时上方多出一截空隙 → C10-09 论点 5 与 C10-09 坑 8。G. 无障碍与文案的供给侧
I11 论点 7,二维码遮罩在六十个语言包里没有对应块(C10-07 §五)。C10-00 坑 1(组内路径把键名拼错);但只补拼写不解决任何用户可见问题,原因见 C10-01 坑 7。C10-04 坑 6。C10-02 坑 3(左右插槽与裁剪区间反号)、C10-04 论点 6(dir 被硬编码)、C10-09 坑 7(只有一行方向声明而间距全是物理属性)。H. 内核来源与注入面(本类最该记住的一族)
C10-07 §一)。结论:本类的出口不做净化,注入面由调用方自己负责。C10-06 坑 1。这一条在该篇已标注「按源码选项字面量推出的可达通路、未在浏览器实测」,引用时按条件句使用,不要写成已实测结论。C10-07 取舍一);npm 路线的失配方式是引擎方法被依赖版本删掉,而唯一的测试用 mock 把那个方法补了回来(C10-08 论点 5)。I. 绿色但不覆盖的测试面
C10-07 论点 5(内核调用零执行、另一种介质零覆盖)、C10-08 论点 5(mock 清单照被测代码写)、C10-06 坑 7(无 canvas 环境时整段绘制被跳过)、C10-05 坑 3(靠 monkey-patch 才让分支可达)。C10-09 §七);图片侧的预览交互是零覆盖,且 vc-image 目录下没有任何测试文件(C10-01 §七)。C10-01 论点 3、C10-00 取舍二、C10-00 坑 4。这是公开行为变更,不是内部修复。C10-04 论点 5、C10-04 坑 5、C10-04 坑 2、C10-04 取舍二。厂商层不在类型检查内,所以这族改动只能靠行为验证。C10-07 坑 4、C10-08 论点 4、C10-06 坑 2。三处症状同名但优先级方向相反,判据都在 JSX 属性顺序上。C10-07 取舍一、C10-04 取舍二、C10-08 论点 5、C11-08 论点 2。改前先确认许可与版本追溯怎么补。C10-06 取舍一、C10-07 取舍五、A03 论点 4。水印那一步要先放弃「无类名即免疫」这条防御收益。C10-09 论点 1、C10-09 坑 2、C10-05 论点 1。坑 1 与坑 2 是同一个契约的两半,只修一半会更糟。C10-07 论点 5、C10-06 坑 7、C10-08 论点 5、C10-05 坑 3。补桩顺序比补断言顺序重要,否则新用例照样是绿的。I11 论点 7、C10-04 坑 6、C10-07 §一。这一族的根因在供给侧,逐组件补读取点没有用。