今天會繼續實現我們表單中的「自訂資料夾」的功能
所以會用到async component
會把「資料夾」的資料做成 async API
父層是BookForm.vue
子層是AsyncSelectBookFolder.vue
並且包含 Folder Name List
檔案AsyncSelectBookFolder.vue
我們會用到defineEmits
, defineProps
,watch
並且使用Vue 3 的 Composition API 來定義一些組件的邏輯
<script setup lang="ts">
import { ref,watch } from "vue";
import { getBookFolders } from "../firebase";
import { DocumentData } from "firebase/firestore";
const folders = ref(<DocumentData>[]);
folders.value = await getBookFolders();
const selectedFolder = ref(folders.value[0].title);
const emit = defineEmits(["updateSelectFolderName"]);
const sendValueToParent = () => {
emit("updateSelectFolderName", selectedFolder.value);
};
// 定義接受的 props
const props = defineProps({
selectFolderName: {
type: String,
default: "",
},
});
watch(() => props.selectFolderName, (forlderName) => {
selectedFolder.value = forlderName;
});
</script>
這裡定義了一個 ref 叫 folders
並使用 getBookFolders
API 非同步地從 Firebase 中取得資料夾資料
然後把取得的資料設定到 folders 的 value
const emit = defineEmits(["updateSelectFolderName"]);
const sendValueToParent = () => {
emit("updateSelectFolderName", selectedFolder.value);
};
定義了一個觸發事件的函數 emit
以及sendValueToParent
方法
可以updateSelectFolderName
事件並
傳遞 selectedFolder.value
到父組件
const props = defineProps({
selectFolderName: {
type: String,
default: "",
},
});
watch(() => props.selectFolderName, (folderName) => {
selectedFolder.value = folderName;
});
做一個下拉選單
<template>
<div class="mb-2">
<i class="i-lucide:folder-search">資</i><label>資料夾位置</label>
<select
v-model="selectedFolder"
@change="sendValueToParent"
class="w-full px-3 py-2 box-border border rounded"
>
<option v-for="folder in folders" :key="folder.id" :value="folder.title">
{{ folder.title }}
</option>
</select>
</div>
</template>
這裡是檔案BookForm.vue
import AsyncSelectBookFolder from '../components/AsyncSelectBookFolder.vue';
//....
const handleFolderNameUpdate = (folderName:string) => {
bookInfo.value.folderName = folderName;
}
寫入子元件
<Suspense>
<template #default>
<!-- <MyAsyncComponent></MyAsyncComponent> -->
<!-- .... 省略其他表格內容 -->
<AsyncSelectBookFolder @updateSelectFolderName="handleFolderNameUpdate" :selectFolderName="bookInfo.folderName"></AsyncSelectBookFolder>
</template>
<template #fallback>
<Loading></Loading>
</template>
</Suspense>
我們會使用 Vue 3 中的 <Suspense>
元素
用於實現異步加載和處理資料的情況
加載時顯示"Loading..."的效果
並在資料加載完成後顯示實際的內容
如果沒使用Suspense
AsyncComponent 可能無法正常顯示
@updateSelectFolderName="handleFolderNameUpdate"
:
可以監聽子元件 <AsyncSelectBookFolder>
發送的 updateSelectFolderName
事件
當子元件觸發這個事件時
將調用 handleFolderNameUpdate
方法
並將新的 selectFolderName
值作為參數傳遞給它
那我們這一章節就先介紹到這邊
下一篇接續實現其他功能^^