当前位置: 首页 > wzjs >正文

用python做的网站深圳网络运营推广公司

用python做的网站,深圳网络运营推广公司,全屏网站宽度,如何制作app应用Vue2 中 el-dialog 封装组件属性不生效的深度解析(附 $attrs、inheritAttrs 原理) 在使用 Vue2 和 Element UI 进行组件封装时,我们常会遇到父组件传入的属性不生效的情况,比如在封装的 el-dialog 组件中传入 width"100%&qu…

Vue2 中 el-dialog 封装组件属性不生效的深度解析(附 $attrs、inheritAttrs 原理)

在使用 Vue2 和 Element UI 进行组件封装时,我们常会遇到父组件传入的属性不生效的情况,比如在封装的 el-dialog 组件中传入 width="100%",却发现宽度没有变化。

本文将围绕这个问题,结合实际代码场景,详细解释:

  • 为什么属性没有传递进去?
  • $attrsinheritAttrs 的作用是什么?
  • 为什么写 :width="width" 又能生效?
  • 封装组件的最佳实践是什么?

🚩 一、问题场景:传入 width 却不生效

封装组件中我们这样写了 el-dialog

<template><div><el-dialog:title="title":visible.sync="visible"width="30%"            <!-- 👈 这里写死了 -->v-bind="$attrs"        <!-- 👈 希望传入的 width 覆盖它 -->><slot></slot></el-dialog></div>
</template>

父组件使用方式如下:

<XjDialog title="二维码预览" :visible="true" width="100%" />

预期: 宽度应该是 100%
结果: 仍然是 30%

🎯 二、问题本质:Vue2 中属性的默认行为

- ✅ Vue2 的处理规则:

  • 父组件传入的属性,如果在子组件中没有在 props 中声明,就会被 Vue 自动加入到 $attrs 对象中。
  • 如果子组件没有设置 inheritAttrs: false,Vue 会默认把 $attrs 中的属性添加到组件的根 DOM 元素上(通常是 div)
  • 这些属性不会自动传递给 el-dialog,除非你手动传

- ⚠️ 所以:

你以为的:
<el-dialog width="100%">...</el-dialog>
实际变成了:
<div width="100%">      <!-- ❌ width 被绑定在根 div 上 --><el-dialog width="30%">...</el-dialog>  <!-- ✅ 仍然是 30% -->
</div>

🧠 三、深入理解:为什么 :width=“width” 又生效了?

在排查时,你发现:只要你加上了 :width=“width”,比如:

<el-dialog :width="width" v-bind="$attrs" />

传入的 width=“100%” 就起作用了!这是为什么?

- ✅ 解释:

  • 当你写 :width=“width” 时,Vue 会去组件实例中查找 width
  • 你并没有在 data 或 computed 中声明 width,Vue 就自动去 $attrs 中找
  • 找到了 $attrs.width = ‘100%’,于是绑定成功!

实际上等同于:

<el-dialog :width="$attrs.width" />

所以你看到 :width=“width” 生效了

⚠️ 这种行为是 Vue 的“隐式变量继承”,虽然方便但不推荐依赖,容易混淆。

🛠️ 四、解决方案:组件封装推荐写法

✅ 推荐完整写法:

<script>
export default {inheritAttrs: false, // 避免 $attrs 被自动绑定到最外层 DOM 上props: {visible: Boolean,title: String,showFooter: {type: Boolean,default: true},cancelText: {type: String,default: '取消'},confirmText: {type: String,default: '确定'}}
};
</script><template><div><el-dialog:title="title":visible.sync="visible"v-bind="$attrs":before-close="beforeClose"@close="close"><slot></slot><template v-if="showFooter" v-slot:footer><slot name="footer"><el-button @click="handleCancel">{{ cancelText }}</el-button><el-button type="primary" @click="handleConfirm">{{ confirmText }}</el-button></slot></template></el-dialog></div>
</template>

✅ 父组件传参方式:

<XjDialogtitle="预览二维码":visible="qrVisible"width="80%"            <!-- 自动生效 -->:showFooter="false"
/>

✅ 五、几点小结与经验总结

问题 / 点解释
$attrs包含所有父组件传入但未被 props 接收的属性
默认行为Vue 会自动把 $attrs 加在最外层 DOM(通常是 <div>)上
inheritAttrs: false禁止 Vue 自动绑定 $attrs,让你可以手动控制它的传递位置
v-bind="$attrs"手动把 $attrs 绑定到你真正想让它生效的组件上
:width="width" 能用Vue 没找到 width 定义,于是从 $attrs.width 自动取值

🔚 六、最佳实践总结

  • 项目
  1. 封装组件时建议使用:
  2. 统一使用 $attrs 显式传递:
  3. 不要在封装组件中写死属性(如 width=“30%”),这样会覆盖外部传入的设置
  4. 避免使用 :width=“width” 这类“隐式方式”,建议显式写 a t t r s . w i d t h 或统一使用 v − b i n d = " attrs.width 或统一使用 v-bind=" attrs.width或统一使用vbind="attrs"

✅ 最后总结一句话:

封装组件时,如果你希望父组件传入的属性(如 width)能真正传递给内部子组件(如 el-dialog),必须使用 inheritAttrs: false 并配合 v-bind="$attrs" 来手动管理这些属性,否则会出现“属性传了但不生效”的问题。

希望这篇记录能帮助你理解 Vue 的属性机制,也能帮你在写封装组件时少踩坑!

http://www.dtcms.com/wzjs/11743.html

相关文章:

  • wordpress可以做下载站seo监控系统
  • 施工企业主要负责人对安全生产的成都官网seo厂家
  • 2022中央农村工作会议公报谷歌优化
  • 2016网站设计趋势毕业设计网站
  • 哈尔滨道外区建设局官方网站网站宣传方式有哪些
  • 优秀 网站设计 蓝色百度推广天津总代理
  • visio画网站开发类图上海培训机构白名单
  • 软件工程师证书报考网站扬州百度关键词优化
  • wordpress链接在哪里设置密码360优化大师历史版本
  • 网络规划设计师资料济南seo官网优化
  • 免费网站建设教程视频百度seo服务公司
  • 站长统计app软件下载官网做网站的公司有哪些
  • 做网站怎么才能找到靠谱的网络公司百度收录关键词
  • 美观网站建设物美价廉重庆百度关键词推广
  • 垃圾ip段做网站seo公司资源
  • 个人全屏网站模板seow是什么意思
  • 做内销的网站推荐网站推广在哪好
  • 中国人民建设银行官方网站百度搜索引擎广告投放
  • 母婴网站建设的目的如何推广一个网站
  • 做网站建设的利润店铺运营
  • 如何在国外网站做免费推广北京百度seo关键词优化
  • 塘厦 网站建设 百度推广线上推广方案
  • 网站制作复杂吗湖南网站seo找行者seo
  • 网站设计说明书整合b站推广2024mmm已更新
  • 大连做网站优化公司网站及推广
  • 中企动力网站价格谷歌play商店
  • 家里的电脑ip做网站电商运营入门基础知识
  • 企业退休做认证进哪个网站关键词优化技巧有哪些
  • 品牌型网站建设方案软文公司代写
  • 电暖怎么做网站网页设计主题参考