el-dialog關(guān)閉再打開后窗口內(nèi)容不刷新問題及解決
頁面中有增加和編輯兩個功能,由于彈窗樣式都是一樣的,于是將它拆分成一個子組件,父組件把狀態(tài)傳給子組件,子組件根據(jù)這個狀態(tài)判斷是做編輯操作還是新增操作.
編輯:
添加:
問題一:但是這樣遇到了一個問題,在編輯時,只有第一次點編輯時,回顯的數(shù)據(jù)才能正確顯示。
隨后再點其他部門的編輯,數(shù)據(jù)顯示不正確了,還是第一次點開的那個部門的數(shù)據(jù).
原因:現(xiàn)在的代碼中,獲取部門詳情這個動作在子組件的created中發(fā)出的,而created鉤子只會執(zhí)行一次:后續(xù)點擊關(guān)閉彈層時,子組件被沒有銷毀,它只是隱藏了。
問題二:點擊編輯之后再點擊添加,添加表單中也會出現(xiàn)部門詳情數(shù)據(jù)
原因:是關(guān)閉彈窗時,子組件被沒有銷毀,它只是隱藏了,也沒有清空里面表單的數(shù)據(jù)
我們先來看問題一數(shù)據(jù)不更新
問題一:回顯數(shù)據(jù)不更新
解決方案一:在父組件中
給父組件中的el-dialog添加destroy-on-close屬性
查閱了 Dialog 對話框 相關(guān)文檔:
我們可以給它加上這個屬性
<el-dialog :title="isEdit?'編輯':'新增'" :visible.sync="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="resetForm" > <!-- element ui 中dialog的方法destroy-on-close,關(guān)閉時銷毀 Dialog 中的元素 --> <deptDialog :id="fatherId" :origin-list="originList" :is-edit="isEdit" destroy-on-close @success="doSuccess" @doClose="dialogVisible=false" /> </el-dialog>
解決方案二:直接在內(nèi)容上加上屬性 v-if="dialogVisible"
v-if="dialogVisible",關(guān)閉和打開彈層,銷毀和創(chuàng)建組件
v-if會由false=>true,會觸發(fā)beforeCreate,created,beforeMount,mounted 鉤子。
由true=>false,會觸發(fā) beforeDestroy,destroyed 鉤子。
所以我們只要給它加上v-if,取值為控制彈窗顯示隱藏的值,我們打開彈窗時它就會重新重建,關(guān)閉彈窗的話就會銷毀,
這樣每次打開彈窗都會執(zhí)行created鉤子里的獲取部門詳情函數(shù),問題就解決了
這樣做雖然簡單,但是它會有性能消耗,其中的ajax請求也會隨著組件的創(chuàng)建和銷毀重復執(zhí)行
<el-dialog :title="isEdit?'編輯':'新增'" :visible.sync="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="resetForm" > <!-- 解決數(shù)據(jù)不更新的問題:v-if="dialogVisible",關(guān)閉和打開彈層,銷毀和創(chuàng)建組件 --> <deptDialog v-if="dialogVisible" :id="fatherId" :origin-list="originList" :is-edit="isEdit" @success="doSuccess" @doClose="dialogVisible=false" /> </el-dialog>
解決方案三:在父組件中通過引用找到子組件
在父組件中,每次打開彈層時,找到子組件,要求它去發(fā)請求獲取詳情
添加ref引用:
<el-dialog :title="isEdit?'編輯':'新增'" :visible.sync="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="resetForm" > <!-- 添加引用: ref="deptDialog" --> <deptDialog :id="fatherId" ref="deptDialog" :origin-list="originList" :is-edit="isEdit" @success="doSuccess" @doClose="dialogVisible=false" /> </el-dialog>
在編輯時:找到子組件,要求它去發(fā)請求獲取詳情
// 編輯 doEdit(id) { //isEdit設(shè)為true,表示當前狀態(tài)為編輯 this.isEdit = true this.fatherId = id this.dialogVisible = true // 解決數(shù)據(jù)不更新的問題: this.$refs.deptDialog.loadDepartDetail() // 注意:由于DOM更新是異步的,此處要用$nextTick() this.$nextTick(() => { this.$refs.deptDialog.loadDepartDetail() }) //或者放在宏任務(wù)里,如延時器中 // setTimeout(() => { // this.$refs.deptDialog.loadDepartDetail() // }, 0) },
子組件:
created() { //加載部門負責人列表數(shù)據(jù) this.loadEmployeesSimples() //如果為編輯狀態(tài),獲取部門詳情 if (this.isEdit) this.loadDepartDetail() },
解決方案四:在子組件內(nèi)監(jiān)聽id的變化(不推薦使用)
在子組件內(nèi)部添加一個偵聽器:監(jiān)聽當前id的變化
created() { //加載部門負責人列表數(shù)據(jù) this.loadEmployeesSimples() //如果為編輯狀態(tài),獲取部門詳情 if (this.isEdit) this.loadDepartDetail() }, watch: { id: function(newVal, oldVal) { //調(diào)用獲取部門詳情函數(shù) this.loadDepartDetail() } }, //上面這種寫法不會立即觸發(fā),還需在created()中調(diào)用一次,用下面這種方法就不需要在created()中調(diào)用了 //watch: { // id: { // handler: function(newVal, oldVal) { // this.loadDepartDetail() // }, // immediate: true // } // }, //immediate表示在watch中首次綁定的時候,是否執(zhí)行handler,值為true則表示在watch中聲明的時候,就立即 //執(zhí)行handler方法,值為false,則和一般使用watch一樣,在數(shù)據(jù)發(fā)生變化的時候才執(zhí)行handler。所以當為 //true時 在created周期里就可以不用在寫 已經(jīng)在watch 中寫過的方法了
但是這種方法在清空表單數(shù)據(jù)的時候會有一個bug,不推薦使用,后面會詳細講到.
解決方案五:給子組件添加key值
key就是給每一個vnode的唯一id,可以依靠key
更準確地拿到oldVnode中對應的節(jié)點。
避免組件“原地復用”帶來的副作用,加上key,可以讓組件在數(shù)據(jù)變化時強制更新組件。
<el-dialog :title="isEdit?'編輯':'新增'" :visible.sync="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="resetForm" > <!-- 給子組件添加key值 --> <deptDialog :id="fatherId" :key="fatherId" :origin-list="originList" :is-edit="isEdit" @success="doSuccess" @doClose="dialogVisible=false" /> </el-dialog>
問題二:添加表單中也會出現(xiàn)部門詳情數(shù)據(jù)
還是上面說到的問題,關(guān)閉彈層時,子組件被沒有銷毀,它只是隱藏了,所以我們需要手動清除表單中的數(shù)據(jù).
(方案一添加destroy-on-close屬性,方案二v-if="dialogVisible",方案五給子組件添加key值,不會出現(xiàn)這個問題)
分析:有如下三個操作都需要我們?nèi)ブ刂帽韱?/strong>
- 取消
- 確定
- 用戶直接點擊關(guān)閉
所以我們可以在Dialog的@close的回調(diào)中寫一次代碼就行了
父組件:
// 給父組件添加 @close="resetForm" <el-dialog :title="isEdit?'編輯':'新增'" :visible.sync="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="resetForm" > //給子組件添加 ref="deptDialog" <deptDialog v-if="dialogVisible" ref="deptDialog" :origin-list="originList" :is-edit="isEdit" @success="doSuccess" @doClose="dialogVisible=false" /> </el-dialog> // 重置子組件表單 resetForm() { // 調(diào)用子組件中的重置表單方法 this.$refs.deptDialog.resetForm() }
子組件:
// 在父組件中 dialog close時,來調(diào)用 resetForm() { // resetFields是element-ui中的el-form組件提供一個api,它的作用是: // 1. 重置表單數(shù)據(jù) // 2. 清空校驗結(jié)果(頁面上紅色的提示) this.$refs.deptForm.resetFields() }
清空表單數(shù)據(jù)的bug
問題重現(xiàn)
- 選中a部門,進行編輯,故意讓編輯出錯,在表單上出現(xiàn)錯誤
- 點擊取消
- 再次對a部門進行編輯,發(fā)現(xiàn)數(shù)據(jù)沒有顯示出來
原因分析
上面的操作中,前后兩次編輯的是同一個部門,所以子組件內(nèi)對id的watch并沒有執(zhí)行,導致內(nèi)容為空
所以不推薦使用方案四,對id進行偵聽
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue如何監(jiān)聽對象或者數(shù)組某個屬性的變化詳解
這篇文章主要給大家介紹了關(guān)于vue如何監(jiān)聽對象或者數(shù)組某個屬性的變化,在Vue.js中可以通過watch監(jiān)聽屬性變化并動態(tài)修改其他屬性的值,watch通過監(jiān)聽器函數(shù)接收新舊值,實現(xiàn)屬性間的數(shù)據(jù)聯(lián)動,需要的朋友可以參考下2024-12-12Vue3項目頁面實現(xiàn)echarts圖表漸變色的動態(tài)配置的實現(xiàn)步驟
在開發(fā)可配置業(yè)務(wù)平臺時,需要實現(xiàn)讓用戶對項目內(nèi)echarts圖表的動態(tài)配置,讓用戶脫離代碼也能實現(xiàn)簡單的圖表樣式配置,顏色作為圖表樣式的重要組成部分,其配置方式是項目要解決的重點問題,所以本文介紹了Vue3項目頁面實現(xiàn)echarts圖表漸變色的動態(tài)配置2024-10-10vue+iview框架實現(xiàn)左側(cè)動態(tài)菜單功能的示例代碼
這篇文章主要介紹了vue+iview框架實現(xiàn)左側(cè)動態(tài)菜單功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07vue+element開發(fā)使用el-select不能回顯的處理方案
這篇文章主要介紹了vue+element開發(fā)使用el-select不能回顯的處理方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07