跳到正文

Teleport 弹窗尺寸为什么会丢

公共弹窗的宽度都配置为 375px,一个显示正常,另一个却窄得像不到 200px。差异出现在尺寸绑定从模板 :style 改成 CSS v-bind() 之后:脚本中的宽度还在,scoped 样式也能匹配,第一次打开的新节点却没有得到变量。

这个弹窗使用 Teleport 把 DOM 放到 body,用 Transition 处理进入和离开,再由 CSS v-bind() 设置尺寸。只改宽度后样式恢复,关闭重开又失效。理解这个现象,需要同时知道新根在哪里创建、哪次组件更新在执行,以及变量更新器怎样找到它。

首次挂载时范围内只有占位,打开后内部组件创建新根却没有触发 Teleport 回填,CSS v-bind 因而缺值

阅读顺序

篇目 要回答的问题
1.Teleport 怎样管理两个 DOM 位置 为什么 DOM 可以放到外部,组件关系却不变;两组锚点、挂载、移动与卸载各负责什么。
2.Transition 怎样协调创建和移除 为什么 open 关闭后旧元素仍在离场;默认插槽、内部渲染任务与 renderer 钩子怎样配合。
3.CSS v-bind 怎样编译与更新变量 CSS 为什么不能直接读取 ref;编译产物、根变量、继承与 Teleport owner 分别负责什么。
4.首次打开的变量漏填与修复 新根为何绕过回填;宽度变化为什么可能掩盖问题;应用层绕法与候选补丁怎样覆盖首次打开。

复现、依赖收集与候选补丁见第 4 篇:首次打开的变量漏填与修复。

版本与验证范围

源码与示例固定在 Vue 3.5.44 的 VDOM runtime。bug 分析沿用 2026 年 10 月的源码核验、浏览器对照和本地测试记录;候选补丁有自己的 Git 基线,仍是本地验证方案。文章保留具体环境、首次打开与后续更新的区别,不能把已测路径当成已发布版本的修复保证。