el-dialog關(guān)閉再打開后窗口內(nèi)容不刷新問題及解決
頁(yè)面中有增加和編輯兩個(gè)功能,由于彈窗樣式都是一樣的,于是將它拆分成一個(gè)子組件,父組件把狀態(tài)傳給子組件,子組件根據(jù)這個(gè)狀態(tài)判斷是做編輯操作還是新增操作.
編輯:

添加:

問題一:但是這樣遇到了一個(gè)問題,在編輯時(shí),只有第一次點(diǎn)編輯時(shí),回顯的數(shù)據(jù)才能正確顯示。
隨后再點(diǎn)其他部門的編輯,數(shù)據(jù)顯示不正確了,還是第一次點(diǎn)開的那個(gè)部門的數(shù)據(jù).
原因:現(xiàn)在的代碼中,獲取部門詳情這個(gè)動(dòng)作在子組件的created中發(fā)出的,而created鉤子只會(huì)執(zhí)行一次:后續(xù)點(diǎn)擊關(guān)閉彈層時(shí),子組件被沒有銷毀,它只是隱藏了。
問題二:點(diǎn)擊編輯之后再點(diǎn)擊添加,添加表單中也會(huì)出現(xiàn)部門詳情數(shù)據(jù)
原因:是關(guān)閉彈窗時(shí),子組件被沒有銷毀,它只是隱藏了,也沒有清空里面表單的數(shù)據(jù)
我們先來(lái)看問題一數(shù)據(jù)不更新
問題一:回顯數(shù)據(jù)不更新
解決方案一:在父組件中
給父組件中的el-dialog添加destroy-on-close屬性
查閱了 Dialog 對(duì)話框 相關(guān)文檔:

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

