?前言:
? ? ? ? 今天上午碰見一個非常奇怪的情況:一樣的方法實現的功能,效果卻不一樣。
兩個頁面都是使用的doClose()去關閉的el-popover,其中有一個就是不生效,找不同找了半天,始終不得其解。請看效果吧:
el-popover-doClose()-ok
視頻1(el-popover-doClose()-關閉成功的)
el-popover-doClose()-error
視頻2(el-popover-doClose()-關閉不成功)?
代碼完全一樣,我把第二個頁面的html部分copy到第一個頁面中也用的很流暢。請各位大佬如果碰見過,踩過坑就給分析分析,留個言哈。
其實仔細看視頻2,第一條數據確實是已經調接口刪除成功了的,但是問題是popover還是沒有關閉。
使用doClose()的原因:之前不知道el-popover上面有doClose()這個方法,也是百度查的。打印了一下它的REF才知道它上面確實有這個方法:
這個方法是可以替代v-model="visible"來控制顯示隱藏的(顯示用doShow()這個方法)主要還是因為是在table列表中,內容比較多,感覺用不了這個動態綁定v-model='visible + scope.row.id' 這種寫法,但我記得好像失敗了,最終才選擇了用doClose()的方案。
但這些不是重點,重點是兩個頁面同種寫法結果一個能關,另一個不能關,我就很費解。真的試了很久,依然不行,最終還是百度一下了。
看了好幾篇博文,基本用的都是一種方法,但是他們給出的原因都是表格懶加載導致,可是我也沒加這個屬性,所以不能說服我,還說VUE不能檢測到ref的值變化 不能觸發視圖更新(這個感覺靠點譜,但是視頻1為什么行呢?)。不過他們給出的方法倒是真的很有效:
handleConfirm() {document.body.click() // 模擬點擊頁面其它部分關掉彈層,因為該頁面列表使用懶加載導致doClose無效
}
在合適的位置添加一句document.body.click(),我的理解就是相當于模擬用戶在別的空白處觸發一個click()事件,這樣自然能實現關閉el-popover的效果。
真的是解決了這個問題。
然后我又去問通義靈碼:
全部答案我放在code中吧:
//問題:el-popover 使用 doClose() 關閉窗口為什么不生效在 Element UI 中,el-popover 組件通常通過綁定 v-model 或 visible 屬性來控制其顯示和隱藏狀態。當用戶希望在特定條件下關閉 el-popover 時,通常會觸發一個方法,比如 doClose,來改變 v-model 或 visible 的值。然而,如果你遇到 doClose 方法不起作用的情況,可能存在以下幾個原因:方法未正確綁定:確保 doClose 是一個在 Vue 實例中的方法,并且在模板中正確引用。
如果使用 ref 訪問 el-popover,確保 ref 已正確定義,例如 ref="popover",并且在方法中使用 this.$refs.popover.close() 調用。
事件觸發問題:如果 doClose 是在某個事件回調中觸發,如點擊事件,確保事件已正確綁定并且觸發條件正確。
異步更新隊列:Vue.js 使用異步更新隊列來處理數據變化。如果你在事件處理函數中直接改變 v-model 或 visible,可能需要使用 Vue.nextTick 或者 Promise.then 來確保在 DOM 更新之后關閉 el-popover。
懶加載導致的問題:如你所述,如果列表使用了懶加載,可能在某些情況下,doClose 方法不會被觸發,因為焦點仍然在列表的某個元素上,沒有真正離開觸發 el-popover 顯示的元素。在這種情況下,可能需要通過模擬點擊頁面其他部分(如 document.body.click())來強制關閉。
CSS 選擇器問題:如果 el-popover 的關閉按鈕或者觸發器被其他元素覆蓋,可能導致點擊事件無法正確傳播,從而影響 doClose 方法的調用。
組件實例問題:如果 el-popover 是動態生成的,可能需要確保每個實例都有唯一的 ref,以便正確地訪問和關閉相應的實例。
權限或角色問題:如果 doClose 包含了角色或權限檢查,而當前用戶沒有足夠的權限,那么方法可能不會執行。
解決這類問題通常需要檢查相關代碼以確定具體的原因。如果 doClose 是 Element UI 自帶的方法,確保你正確理解其用法,因為 Element UI 的官方文檔通常會提供正確的使用示例。如果 doClose 是自定義的方法,那么需要檢查該方法的實現和調用上下文。//問題:前端中document.body.click() 的作用在前端開發中,document.body.click()?這段代碼的作用是模擬一個點擊事件發生在頁面的body上。具體來說,這段代碼有以下幾點作用和考慮:觸發頁面默認行為:通過模擬點擊整個頁面的body,可以觸發瀏覽器或頁面上綁定的一些默認點擊處理邏輯。這可能包括關閉某些彈出層、菜單或者重置焦點等交互效果。解決特定場景問題:在您提供的Vue代碼片段中,提到是因為列表使用了懶加載機制導致原本的關閉方法(假設為doClose)未能正常工作。在這種情況下,直接觸發document.body.click()可能是一種變通方法,用來間接觸發表單、對話框或其他組件的關閉邏輯,這些邏輯可能依賴于頁面的點擊事件來觸發。重置狀態或焦點:在一些交互設計中,點擊頁面空白區域常用于重置當前界面狀態或返回到初始焦點位置,比如關閉一個模態窗口后讓頁面背景可交互。兼容性處理:在不同的瀏覽器和環境中,直接調用click()方法可能有兼容性問題,但通常在大多數現代瀏覽器中此操作是被支持的。不過,這種方式更多被視為一種hack手段,因為它繞過了正常的事件觸發流程。需要注意的是,這種做法雖然有時能解決特定問題,但并不總是最佳實踐。它可能會導致不可預知的副作用,比如意外觸發其他監聽在body上的點擊事件。在實際開發中,更推薦明確地管理組件的狀態和事件處理邏輯,盡量避免使用全局性的模擬點擊來控制UI行為。如果doClose方法無效,應該首先檢查并修復其背后的邏輯或監聽機制,而不是依賴于模擬點擊整個頁面body作為解決方案。
你別說還真挺專業的是吧,聽完還是有些收獲的,不過我感覺是其他因素導致的,不讓第一個視頻不會成功,目前我還沒有找到問題關鍵,將來會跟新吧(如果有時間調研一下)
補充一下:
不過我擔心確實點擊事件綁在body上不太好,所以我在頁面上單獨寫了一個用不到的DIV標簽:
<div id="qwer" />
然后使用document.getElementById("qwer").click(),把事件綁在這個上面依舊有效,可以達到關閉el-popover的效果
不過按照通義靈碼上講到的,我這算不算是一種hack行為呢?
還有就是請問視頻1為什么不用添加document.body.click()這種寫法doClose()就生效呢?