前言
這篇主要是想分享在用vue做前端專案時遇到modal的一些問題和我自己整理後的解決方法,希望能幫助到一些跟我一樣在網路上搜尋”Vue Bootstrap modal”的人,分享若有錯誤或不完善的地方再麻煩告知,也歡迎提供更好的方法一起交流。
遇到的問題
我想要用Vue實作以Bootstrap modal的方式呈現登入頁面/註冊頁面等,但就在我把版都刻好後要開始Post API時,發現雖然成功請求並轉址了,但modal卻還停留在畫面上,很不符合使用者體驗!於是開始搜尋了一些相關解法,發現確實不少人在討論這個問題,而我研究後發現了三個方法,各有好壞,那我們就看下去吧!
要討論這個問題就要先了解Bootstrap實作Modal方法的原理,這也說到了一個解法 — jQuery!
方法1 — jQuery
由於Bootstrap官方文件在展示modal時,就有提到若要手動隱藏modal,可以直接使用jQuery來進行, 如下圖,此法非常有效且直接,直接利用jQuery提供的dollar sign($)綁定欲控制的modal元素(要在該頁面import $),並用.modal(‘hide’)就可以輕鬆在請求結束時輸入後隱藏modal。但此法有個缺點,那就是網路上以及友人都不建議在使用Vue框架時搭配jQuery實作,主要的論點如下:
- jQuery直接對 DOM 操作 (太過頻繁會造成消耗效能非常大)
- jQuery可能會破壞DOM與 Vue.js 的綁定
- 兩者操作的觀念不同 (jQuery 直接去動「網頁上的元素」,而 Vue.js 通常只會和資料有所互動)
備註:最後因為我整個專案用到jQuery的方法很少,所以先用此法改善,但未來我可能會用以下其他提到的方法改進。
方法二- 讓頁面重新整理
可以利用location.reload()搭配setTimeout,讓Post API請求完資料後重新整理,modal就會自動刷新,此法雖直接簡單,但也會遇到一些問題,例如刷新頁面對使用者體驗就沒那麼順暢,或者說想要在頁面請求完資料後轉址到指定處也有難度。
window.setTimeout(function(){location.reload()},3000)
方法三- 利用v-if來綁定modal
這個方法目前無法完整解決在送出post請求後讓modal消失的問題,主要是因為利用v-if來綁定modal元素,當v-if條件不成立時,只會讓modal元素消失,而Bootstrap的modal會因開起modal而在底部插入元素(modal-backdrop,此元素是用來防止點擊到modal以外的地方),此元素並不會跟著消失,如下圖,必須還得另外想辦法綁定到此元素後刪除(網路上分享也是用jQuery綁定元素的class)。
//綁在component
//SignIn.vue
<template>
<div v-if="true/false"
class="modal fade" id="signin" tabindex="-1" role="dialog" aria-labelledby="signinLabel" aria-hidden="true"
>
...
<div class="modal-content" ...>
<form @submit.prevent.stop="handleSubmit">
...
<button type="submit"> Submit </button>
</form>
</div>
</template>//或是綁在父層
//App.vue
<template>
<div id="app">
...
<SignInM v-if="true/false" />
...
<main role="main" class="mt-5">
<router-view />
</main>
</div>
</template>//打開瀏覽器頁面用開發者工具會發現還是會留下backdrop這個元素<html>
...
<div class="modal fade" id="signin" ...>
...
<div class="modal-content" ...>
<form @submit.prevent.stop="handleSubmit">
...
<button type="submit"> Submit </button>
</form>
</div>
...
<div class="modal-backdrop fade show"></div>
</body>
</html>
其他方法-BootstrapVue and others
有人提供在submit的button鍵綁上一個attribute (data-dismiss=”modal”),確實可以成功關閉modal,但是我的實測是資料就不會請求了,可能還需要搭配一些方法,提供給各位參考。
在研究方法時,也發現有開發專門讓vue框架者使用的BootstrapVue(BV),但若要用BV,因為不是用原來的Bootstrap,所以需要改動的元素標籤並不少,目前還是先以讓專案功能完整為優先。
補充:BV裡面有提供b-modal搭配b-button方法使用,可以讓使用者更直覺的使用類似vue的方式來達到想要的效果,有試玩了一下,覺得很不錯用耶,下次在專案開始刻板時就來採用看看BV吧!
最後要感謝網路上的相關文章還有讓心幫我想解法的朋友,才能讓我這麼快找到這麼多解決方法。