【vue】将el-dialog 封装成一个组件报错
一、报错信息
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "isVisibleDialog"
二、概述
场景:点击父组件的<显示弹窗>按钮显示弹窗,
错误出现流程,点击父组件<显示弹窗>按钮,弹窗显示,点击弹窗的取消按钮,关闭弹窗的时候,就报错啦
三、错误写法
父组件
html
<dialog-f :is-visible-dialog="dialogData.isVisibleDialog" />
dialogData: { isVisibleDialog: false, }
methods
handleShowDialog(){ this.dialogData.isVisibleDialog = true; }
子组件
<el-dialog title="" :visible.sync="isVisibleDialog" :show-close="false" :close-on-click-modal="false" width="600px" custom-class="dialog-container" > <div slot="footer" class="mx-dialog-footer dis-flex flex-justify-end"> <div slot="footer" class="mx-dialog-footer dis-flex flex-justify-end"> <el-button class="dialog-footer-cancel" @click="isVisibleDialog=false">取消</el-button> <button class="dialog-footer-confirmed theme-bg-h-hover" type="primary" @click="sure" > 确定 </button> </div> </div> </el-dialog>
props
props: { isVisibleDialog: { type: Boolean, default() { return false; }, } }
错误原因
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:
父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
官网提供了2种接近方案
这里有两种常见的试图变更一个 prop 的情形:
-
这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
-
这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
四、正确写法
父组件
html
<dialog-f :is-visible-dialog="dialogData.isVisibleDialog" />
dialogData: {
isVisibleDialog: 0,
}
methods
handleShowDialog(){
this.dialogData.isVisibleDialog = Math.random()*10 + 1;
}
子组件
<el-dialog
title=""
:visible.sync="isShowDialog"
:show-close="false"
:close-on-click-modal="false"
width="600px"
custom-class="dialog-container" >
<div slot="footer" class="mx-dialog-footer dis-flex flex-justify-end">
<div slot="footer" class="mx-dialog-footer dis-flex flex-justify-end">
<el-button class="dialog-footer-cancel" @click="isVisibleDialog=false">取消</el-button>
<button
class="dialog-footer-confirmed theme-bg-h-hover"
type="primary"
@click="sure"
>
确定
</button>
</div>
</div>
</el-dialog>
props:
props: {
isVisibleDialog: {
type: Number,
default() {
return 0;
},
}
}
data() { return { isShowDialog: false } }
watch: { isVisibleDialog(val) { this.isShowDialog = val ? true : false } }
欢迎关注我,一起进步!扫描下方二维码即可加我QQ

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通