【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"
                            
/>
data:
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 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

官网提供了2种接近方案

这里有两种常见的试图变更一个 prop 的情形:

  1. 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:

    props: ['initialCounter'],
    data: function () {
      return {
        counter: this.initialCounter
      }
    }
  2. 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
本人通过第一方法解决的
 

四、正确写法

父组件

html

<dialog-f
    :is-visible-dialog="dialogData.isVisibleDialog"
                            
/>
data:
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
data() {
    return {
         isShowDialog: false
    }
}    
watch:
watch: {
    isVisibleDialog(val) {
         this.isShowDialog = val ? true : false
    }
    
}

 

 写法二:【vue】将el-dialog 封装为一个组件2

posted on 2022-04-24 17:14  smile轉角  阅读(751)  评论(0编辑  收藏  举报

导航