【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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM