🚀 Vue 2 探秘:visible 和 append-to-body 是谁的小秘密?🤔
- 父组件:identify-list.vue
- 子组件:fake-clue-list.vue
嘿,各位前端探险家!👋 今天我们要在 Vue 2 的代码丛林里挖宝,目标是两个神秘属性:visible 和 append-to-body。它们藏在组件里,像遥控器一样控制对话框的开关和位置。到底是谁定义了它们?它们有啥用?咱们带上放大镜 🔍,一起揭秘吧!✨
🌟 背景:从一个对话框开始
假设你有一个 Vue 2 项目,用的是 Element UI 的 <el-dialog>。代码长这样:
<!-- 父组件 -->
<template><el-dialog :visible="visible" title="识别点"><fake-clue-list :visible.sync="fclVis" @close="onfclClose" /></el-dialog>
</template>
<!-- fake-clue-list.vue 子组件 -->
<template><el-dialog :visible="visible" :append-to-body="true" title="假货线索"><!-- 内容 --></el-dialog>
</template>
点击按钮,子组件的对话框蹦出来,但你突然好奇:visible 和 append-to-body 到底是谁定义的?是自己写的,还是框架给的?别急,咱们一步步解剖!🧑🔬
🎬 第一幕:visible 的身世之谜
它从哪来?
在父组件中,我们看到 <fake-clue-list :visible.sync="fclVis" />,子组件里是 <el-dialog :visible="visible">。这俩 visible 啥关系?
子组件的定义
打开 fake-clue-list.vue,发现:
export default class extends Vue {@Prop({ default: false }) private visible!: boolean
}
@Prop:visible是子组件用 TypeScript 的@Prop装饰器定义的一个 prop,默认值是false。- 作用:接收父组件传来的值(
fclVis),然后绑定到<el-dialog>的:visible。
Element UI 的影子
但等等!<el-dialog> 的 visible 可不是随便起的名字。根据 Element UI 文档:
- 属性:
visible - 类型:
Boolean - 作用:控制对话框显示与隐藏。
子组件的 visible prop 直接传给了 <el-dialog>,这说明:
- 直接定义者:是你(或子组件作者),在
FakeClueList中用@Prop声明。 - 根本来源:Element UI 的
<el-dialog>,它定义了visible这个 prop,子组件只是“借用”并传递。
实验验证
为了确认,我试着注释掉 @Prop:
// @Prop({ default: false }) private visible!: boolean
结果?控制台炸了:
[Vue warn]: Property or method "visible" is not defined on the instance but referenced during render.
对话框也不弹了!这证明:
visible是FakeClueList自己声明的 prop。- 没有它,父组件的
:visible.sync无处对接,<el-dialog>也懵了。😵
流程图:visible 的旅程
用 Mermaid 图展示一下:
🎭 第二幕:append-to-body 的多余冒险
父组件的“热情”
父组件原本是这样的:
<fake-clue-list :visible.sync="fclVis" :append-to-body="true" @close="onfclClose" />
:append-to-body="true" 看起来像是要控制啥,但子组件里呢?
子组件的真相
<el-dialog :visible="visible" :append-to-body="true">
- 硬编码:子组件直接写死了
:append-to-body="true"。 - Prop 检查:脚本中没有:
也就是说,@Prop() private appendToBody!: booleanFakeClueList根本没定义append-to-body作为 prop!
Element UI 的定义
再看 Element UI 文档:
- 属性:
append-to-body - 类型:
Boolean - 默认值:
false - 作用:决定对话框 DOM 是否追加到
<body>。
子组件的 :append-to-body="true" 是给 <el-dialog> 用的,但父组件的 :append-to-body 呢?因为没被子组件接收,它只是个“空气传值”,啥也没干。😂
删除实验
我把父组件的 :append-to-body 删了:
<fake-clue-list :visible.sync="fclVis" @close="onfclClose" />
结果?对话框照样弹出,DOM 依然挂在 <body> 下。为啥?因为子组件的 <el-dialog :append-to-body="true"> 已经全权负责!
🧠 思维导图总结
用 Mermaid 画个思维导图,理清关系:
🎉 结论与收获
-
visible:- 谁定义的:你在
FakeClueList中用@Prop声明。 - 来源:沿用 Element UI 的
<el-dialog>的visible。 - 重要性:没它,对话框开关失灵!
- 谁定义的:你在
-
append-to-body:- 谁定义的:Element UI,在
<el-dialog>中提供。 - 你的用法:子组件写死
true,父组件的传值多余。 - 清理:删掉父组件的
:append-to-body,代码更清爽。
- 谁定义的:Element UI,在
小Tips
- 想动态控制
append-to-body?在子组件加个@Prop,别写死。 - 检查 prop 用没用到,省得像
:append-to-body这样“白传”。
这次探秘是不是很有趣?😎 下次遇到神秘属性,别忘了带上实验精神,一探到底!有啥想法,评论区聊聊吧!👇

