Open HelloChunWei opened 2 years ago
在第一篇中製作了一個很簡單的hook 去呼叫 modal ,(前情提要) 那麼接下來我們就慢慢的把發現的問題給排除吧。
目前的 hook 只能開啟一個 modal,沒辦法透過 openModal 決定開哪一個modal,所以我們先來把這個問題給解決了吧。
那麼要解決這個問題的關鍵技術是利用vue的is,利用 is 就可以去動態的切換 component。
首先我們先建立一個modals/index.vue當作我們的主要進入點:
<template> <!-- 這裡也用 v-if 決定是否顯示,然後利用 is 決定哪個 modal component --> <component v-if="isShow" :is="componentName" /> </template> <script lang="ts"> import { defineComponent, defineAsyncComponent, toRefs } from 'vue' export default defineComponent({ name: 'ModalIndex', props: ['isShow', 'component'], setup(props) { const { component } = toRefs(props) const componentName = defineAsyncComponent(() => import(`./${component.value}.vue`)) return { componentName } } }) </script>
這裡我們也用了 defineAsyncComponent 去動態的引入我們要的 component。 這樣就不用引入全部的 modal 進來了。
接下來修改一下我們的 index.ts:
import { createApp } from 'vue' // 改用 index.vue import Index from './index.vue' type componentNameType = 'testModal' export const useModal = () => { // 在呼叫openModal 的時候順便指定是要用哪一個 modal // component 利用 type 去指定,那目前只有 testModal 所以就先指定為 testModal const openModal = ({ component }: { component: componentNameType }) => { const container = document.createElement('div') // 將 prop 傳入 const vnode = createApp(Index, { isShow: true, component }) document.body.appendChild(container) vnode.mount(container) } return { openModal } }
這樣子後我們要使用的話就是:
// 在需要呼叫的地方引入: import { defineComponent, onMounted } from 'vue' import { useModal } from '@hook/modal/index' export const defineComponent({ setup () { const { openModal } = useModal() onMounted(() => { openModal({ component: 'testModal' }) }) } })
那假設今天我們新增了一個 testModal2.vue 檔案,我們只要修改:
type componentNameType = 'testModal' | 'testModal2'
那在使用的話只要
openModal({ component: 'testModal2' })
這樣就可以直接使用了。
目前我們可以動態切換想要用的 modal ,那們我們該如何關閉它?有一種最簡單暴力的方法,既然我們是在 body 外在新增一層 dom,那我們直接remove 掉就好了。
import { createApp } from 'vue' // 改用 index.vue import Index from './index.vue' type componentNameType = 'testModal' export const useModal = () => { // 在呼叫openModal 的時候順便指定是要用哪一個 modal // component 利用 type 去指定,那目前只有 testModal 所以就先指定為 testModal const openModal = ({ component }: { component: componentNameType }) => { const container = document.createElement('div') // 直接remove const closeModal = () => { document.body.removeChild(container) } // 將 prop 傳入 const vnode = createApp(Index, { isShow: true, component, closeModal // 將 closeModal 傳入 }) document.body.appendChild(container) vnode.mount(container) } return { openModal } }
<template> <!-- 這裡也用 v-if 決定是否顯示,然後利用 is 決定哪個 modal component --> <!-- 將closeModal 在傳入 component --> <component v-if="isShow" :is="componentName" @closeModal="closeModal" /> </template> <script lang="ts"> import { defineComponent, defineAsyncComponent, toRefs } from 'vue' export default defineComponent({ name: 'ModalIndex', props: ['isShow', 'component', 'closeModal'], setup(props) { const { component } = toRefs(props) const componentName = defineAsyncComponent(() => import(`./${component.value}.vue`)) return { componentName } } }) </script>
在 testModal 中使用:
<template> <modal> <template #header> 我是頭 </template> <template #body> body </template> <template> <button @click="$emit('closeModal')"> 關閉 </button> </template> </modal> </template> <script lang="ts"> import { defineComponent } from 'vue' import Modal from './template.vue' export default defineComponent({ name: 'test', emits: ['closeModal'], components: { Modal }, }) </script>
到這裡我們就把上一篇提到的問題給解決了,但是卻還有幾個問題:
第一個問題會是比較嚴重的問題,如果自定義的 modal 無法傳 props 的話,使用的情境就會非常的少,第二以及第三的問題則是屬於重構 code 的問題,目前還不影響 modal 的使用情境。
那這些問題該怎麼解決呢?我們等到下一篇再說吧。
前言
在第一篇中製作了一個很簡單的hook 去呼叫 modal ,(前情提要) 那麼接下來我們就慢慢的把發現的問題給排除吧。
能夠動態決定使用哪個 modal
目前的 hook 只能開啟一個 modal,沒辦法透過 openModal 決定開哪一個modal,所以我們先來把這個問題給解決了吧。
那麼要解決這個問題的關鍵技術是利用vue的is,利用 is 就可以去動態的切換 component。
首先我們先建立一個modals/index.vue當作我們的主要進入點:
這裡我們也用了 defineAsyncComponent 去動態的引入我們要的 component。 這樣就不用引入全部的 modal 進來了。
接下來修改一下我們的 index.ts:
這樣子後我們要使用的話就是:
那假設今天我們新增了一個 testModal2.vue 檔案,我們只要修改:
那在使用的話只要
這樣就可以直接使用了。
該如何關閉 modal?
目前我們可以動態切換想要用的 modal ,那們我們該如何關閉它?有一種最簡單暴力的方法,既然我們是在 body 外在新增一層 dom,那我們直接remove 掉就好了。
在 testModal 中使用:
到這裡我們就把上一篇提到的問題給解決了,但是卻還有幾個問題:
第一個問題會是比較嚴重的問題,如果自定義的 modal 無法傳 props 的話,使用的情境就會非常的少,第二以及第三的問題則是屬於重構 code 的問題,目前還不影響 modal 的使用情境。
那這些問題該怎麼解決呢?我們等到下一篇再說吧。