2024-10-11|閱讀時間 ‧ 約 0 分鐘

EP34 - ex6. Modal

modal是UI/UX設計中,指的是一種會阻止用戶與其他界面交互的視窗,叫做模態視窗(或者叫做模態對話框),用途是聚焦內容!可以好好提供特定資訊這樣~
這個應該不難吧~ 來實做看看吧!

App.vue

<!--
Modal component with customizable slots and CSS transitions.
-->

<script setup>
import Modal from './Modal.vue'
import { ref } from 'vue'

const showModal = ref(false)
</script>

<template>
<p>Example 6:</p>
<button id="show-modal" @click="showModal = true">Show Modal</button>

<Teleport to="body">
<!-- use the modal component, pass in the prop -->
<modal :show="showModal" @close="showModal = false">
<template #header>
<h3>Custom Header</h3>
</template>
</modal>
</Teleport>
</template>

<script setup>

  • import Modal from './Modal.vue':引入一個模態對話框組件。
  • import { ref } from 'vue':從Vue庫中引入 ref 函數,用來創建一個響應式的變數。
  • const showModal = ref(false):創建一個響應式變數 showModal,初始值為 false,用來控制模態對話框的顯示與否。

<template>

  • <button id="show-modal" @click="showModal = true">Show Modal</button>:一個按鈕,當點擊時會將 showModal 設置為 true,從而顯示模態對話框。
<Teleport to="body">
<!-- use the modal component, pass in the prop -->
<modal :show="showModal" @close="showModal = false">
<template #header>
<h3>Custom Header</h3>
</template>
</modal>
</Teleport>
  1. <Teleport to="body">Teleport 組件用來將其子組件渲染到 body 元素中,而不是其原本的位置。
  2. <!-- use the modal component, pass in the prop -->:這是一個註解,說明使用模態對話框組件並傳入屬性。
  3. <modal :show="showModal" @close="showModal = false">:這行代碼用來顯示模態對話框,並將 showModal 作為 show 屬性傳入,同時監聽 close 事件,當模態對話框發出 close 事件時,將 showModal 設置為 false,隱藏模態對話框。
  4. <template #header>:這行代碼用來定義模態對話框的 header 插槽。
  5. <h3>Custom Header</h3>:一個自定義的標題,作為模態對話框的 header 插槽內容。

通過這段代碼,當點擊「Show Modal」按鈕時,模態對話框會顯示,並且可以自定義模態對話框的標題內容。

Q: Teleport哪來的?

Teleport 是 Vue 3 中的一個內建組件,用來將子組件或元素渲染到指定的 DOM 節點,而不是渲染在其父組件的 DOM 節點中。這在某些情況下非常有用,比如需要將模態對話框、提示框等元素渲染到 body 標籤下,以避免層級問題。

在 Vue 3 中,你不需要特別引入 Teleport 組件,它是 Vue 的一部分,可以直接使用。

Teleport 簡介

Teleport 是 Vue 3 的一個特性,用來將元素渲染到指定的 DOM 節點,而不是其原本所在的位置。這對於模態對話框、通知和提示框等需要在頁面上高層級顯示的元素非常有用。

Modal.vue

<script setup>
const props = defineProps({
show: Boolean
})
</script>

<template>
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">default header</slot>
</div>

<div class="modal-body">
<slot name="body">default body</slot>
</div>

<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" @click="$emit('close')">OK</button>
</slot>
</div>
</div>
</div>
</Transition>
</template>

<style>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
transition: opacity 0.3s ease;
}

.modal-container {
width: 300px;
margin: auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
}

.modal-header h3 {
margin-top: 0;
color: #42b983;
}

.modal-body {
margin: 20px 0;
}

.modal-default-button {
float: right;
}

/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/

.modal-enter-from {
opacity: 0;
}

.modal-leave-to {
opacity: 0;
}

.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>

<script setup>

<script setup>
const props = defineProps({
show: Boolean
})
</script>
  • script setup:這是 Vue 3 中一個簡化的腳本語法,專為組件設置而設計。
  • defineProps:用來定義從父組件傳入的 props
  • show:定義了一個布林值的 prop,用來控制模態對話框是否顯示。

<template>

<template>
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">default header</slot>
</div>

<div class="modal-body">
<slot name="body">default body</slot>
</div>

<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" @click="$emit('close')">OK</button>
</slot>
</div>
</div>
</div>
</Transition>
</template>
  • <Transition name="modal">:使用 Vue 的 Transition 組件來為模態對話框的顯示和隱藏添加過渡效果,過渡的名稱為 modal
  • v-if="show":只有在 showtrue 時才會渲染這個 div,即模態對話框。
  • class="modal-mask":遮罩層的 CSS 類,用於覆蓋整個頁面。
  • class="modal-container":模態對話框的容器 CSS 類。
  • <slot name="header">default header</slot>:插槽,用於讓父組件提供自定義的標頭內容。如果父組件沒有提供,則顯示默認內容 default header
  • <slot name="body">default body</slot>:插槽,用於讓父組件提供自定義的主體內容。如果父組件沒有提供,則顯示默認內容 default body
  • <slot name="footer">:插槽,用於讓父組件提供自定義的頁腳內容。如果父組件沒有提供,則顯示默認內容,包括一個關閉按鈕。
  • @click="$emit('close')":當按鈕被點擊時,觸發一個名為 close 的自定義事件,以通知父組件關閉模態對話框。

Q: Transition哪來的?

Transition 是 Vue 內建的組件之一,用於應用過渡效果到元素的進出過程中。當你在模板中使用 <Transition> 標籤時,它會自動應用指定的 CSS 過渡效果到包裹的元素上。

在範例中,Transition 用於模態對話框的進出過程中,使其顯示和隱藏更具動畫效果。以下是更詳細的解釋:

Transition 的來源

在 Vue 3 中,Transition 是一個全局組件,這意味著你不需要顯式地導入它就可以直接使用。它內建在 Vue 的核心庫中,因此可以直接在模板中引用。

<style>

<style>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
transition: opacity 0.3s ease;
}

.modal-container {
width: 300px;
margin: auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
}

.modal-header h3 {
margin-top: 0;
color: #42b983;
}

.modal-body {
margin: 20px 0;
}

.modal-default-button {
float: right;
}

.modal-enter-from {
opacity: 0;
}

.modal-leave-to {
opacity: 0;
}

.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>
  • .modal-mask:定義了模態對話框的遮罩層樣式,使其覆蓋整個頁面,並且具有半透明的黑色背景。
  • .modal-container:定義了模態對話框的容器樣式,包括寬度、邊距、填充、背景色、邊框圓角和陰影。
  • .modal-header h3:定義了模態對話框標頭的樣式,包括顏色和頂部邊距。
  • .modal-body:定義了模態對話框主體的樣式,包括邊距。
  • .modal-default-button:定義了默認按鈕的樣式,使其浮動到右側。
  • .modal-enter-from.modal-leave-to:定義了模態對話框顯示和隱藏時的過渡效果,包括透明度和縮放效果。
這段代碼創建了一個模態對話框組件,使用插槽讓父組件能夠自定義標頭、主體和頁腳內容,並且使用過渡效果使顯示和隱藏更加平滑。
這個範例雖然很短,但是蠻多細節的~
要自己重頭寫一個類似的~不知道寫得出來嗎?www ~

對話框


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.