EP34 - ex6. Modal

閱讀時間約 17 分鐘
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 ~
對話框

對話框


avatar-img
2會員
70內容數
分享生活趣事~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
卡關的人生 的其他內容
引入 PolyGraph 子組件,並使用 ref 和 reactive 來管理標籤及其對應值。AxisLabel.vue 負責顯示每個統計數據標籤,並根據數據計算其在圖形中位置。PolyGraph.vue 則負責繪製多邊形和圓形,並透過 valueToPoint 函數將統計數據轉換為 SVG 坐標。
Tree View 是一種適合於建立父子組件關係的結構,能夠展示多層級的數據,特別適合遞回渲染。這個組件允許用戶雙擊項目將其轉換為文件夾,並通過 TreeItem 組件遞歸渲染子項目。
在 Vue 3 中使用計算屬性來實現表格的排序和篩選功能。通過創建一個可重用的表格組件(DemoGrid),可以輕鬆管理和顯示外部數據。
這段代碼示範了如何從 GitHub 的 API 抓取最新的 Vue.js 提交數據並顯示在網頁上。這是後端 API 串接的一個範例,展示了如何動態地獲取和顯示數據。
看官方文件好累,終於要來看實用範例摟!這篇要做一個Markdown編輯器,真的假的?!
使用 defineAsyncComponent 函數可實現此功能,它接受一個返回 Promise 的加載函數。在大型應用中,組件可以按需加載,並且可與 ES 模塊的動態導入結合使用。還可以使用高級選項處理加載和錯誤狀態,例如設置加載組件和超時設定。
引入 PolyGraph 子組件,並使用 ref 和 reactive 來管理標籤及其對應值。AxisLabel.vue 負責顯示每個統計數據標籤,並根據數據計算其在圖形中位置。PolyGraph.vue 則負責繪製多邊形和圓形,並透過 valueToPoint 函數將統計數據轉換為 SVG 坐標。
Tree View 是一種適合於建立父子組件關係的結構,能夠展示多層級的數據,特別適合遞回渲染。這個組件允許用戶雙擊項目將其轉換為文件夾,並通過 TreeItem 組件遞歸渲染子項目。
在 Vue 3 中使用計算屬性來實現表格的排序和篩選功能。通過創建一個可重用的表格組件(DemoGrid),可以輕鬆管理和顯示外部數據。
這段代碼示範了如何從 GitHub 的 API 抓取最新的 Vue.js 提交數據並顯示在網頁上。這是後端 API 串接的一個範例,展示了如何動態地獲取和顯示數據。
看官方文件好累,終於要來看實用範例摟!這篇要做一個Markdown編輯器,真的假的?!
使用 defineAsyncComponent 函數可實現此功能,它接受一個返回 Promise 的加載函數。在大型應用中,組件可以按需加載,並且可與 ES 模塊的動態導入結合使用。還可以使用高級選項處理加載和錯誤狀態,例如設置加載組件和超時設定。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
Quasar Dialog 的 Invoking custom component 很好用,但是有些困擾的地方,一起來看看有甚麼辦法吧。
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
MVI(Model View Intent),特點是Intent。 Model 負責介面狀態 View 負責顯示資料。 Intent 負責將封裝後的操作告知Model。
MVVM(Model View ViewModel),特點是View跟ViewModel之間做資料綁定。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。
MVP(Model View Presenter)由MVC演變而來。MVC與MVP的差異是View跟Model之間的關係;MVC中是可以直接溝通的;MVP中是不可以直接溝通的,必須要透過 Presenter。 Model 負責資料存取。 View 負責顯示資料,並將使用者的操作傳給P
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
Quasar Dialog 的 Invoking custom component 很好用,但是有些困擾的地方,一起來看看有甚麼辦法吧。
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
MVI(Model View Intent),特點是Intent。 Model 負責介面狀態 View 負責顯示資料。 Intent 負責將封裝後的操作告知Model。
MVVM(Model View ViewModel),特點是View跟ViewModel之間做資料綁定。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。
MVP(Model View Presenter)由MVC演變而來。MVC與MVP的差異是View跟Model之間的關係;MVC中是可以直接溝通的;MVP中是不可以直接溝通的,必須要透過 Presenter。 Model 負責資料存取。 View 負責顯示資料,並將使用者的操作傳給P
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找