在上一篇當中我們只說到了基本的Tags API
現在要更深入實作細節
那就開始吧!
圖片支援
除了標籤外要可以自訂標籤顏色
有鑑於此
我們設計了一顆可愛的新增標籤按鈕
點下它變可以開始CRUD
的功能囉
回到好朋友檔案這裡firebase.ts
const tagRef = collection(db, "bookTags");
export interface TagInfoType {
title: string,
color:string
}
// 新增一個標籤
export const addTag = (tag: TagInfoType) => {
console.log(tag);
return addDoc(tagRef, tag);
};
// 查出所有標籤清單
export const getBookTags = async () => {
const orderedQuery = query(tagRef, orderBy("title"));
const queryDocs = await getDocs(orderedQuery);
const results: DocumentData = [];
if (queryDocs.empty) {
return results;
}
queryDocs.docs.forEach((doc) => {
const data = doc.data();
const id = doc.id;
const folder = { id, ...data };
results.push(folder);
});
return results;
};
// 刪除一個標籤
export const deleteBookTag = async (id: string) => {
await deleteDoc(doc(db, "bookTags", id));
return;
};
這裡我們先寫好相關的型別
並提供給component做使用
export interface TagInfoType {
title: string,
color:string
}
要注意個小技巧是const folder = { id, ...data };
要push到資料裡給Vue的index 使用
我們只要存一個標籤陣列在按鈕送出時同步更新到bookInfo.tags
一樣建立標籤元件AsyncBookTags.vue
...
import { getBookTags, deleteBookTag, addTag, TagInfoType } from "../firebase";
//....
const tagColors = [
"bg-red-100",
"bg-pink-100",
"bg-orange-1",
"bg-yellow-1",
"bg-lime-1",
"bg-[#DAECDA]",
"bg-[#CDE5EC]",
"bg-blue-100",
"bg-lightBlue-1",
"bg-purple-1",
"bg-violet-1",
"bg-[#E7E7E5]",
"bg-[#EEDFDA]",
];
const handleDelete = (id: string) => {
const checkResult = confirm("確定刪除嗎?");
if (checkResult) return deleteBookTag(id);
return;
};
const newTag = ref(<TagInfoType>{
title: "",
color: "",
});
const saveTag = () => {
if (!newTag.value.title) return alert("請填入標題名稱");
if (!newTag.value.color) return alert("請選擇顏色");
addTag(newTag.value);
tags.value.push(newTag.value)
sendValueToParent();
showAddTags.value = !showAddTags.value;
};
const setColor = (color: string) => {
newTag.value.color = color;
};
template
<template>
<div>
<i class="i-iconoir:people-tag">資</i><label class="pr-5">標籤設定</label>
<div class="pb-2 mt-1 flex justify-start items-center flex-wrap">
<div
v-for="tag in tags"
:key="tag.id"
:class="[
'h-8 mb-2 mr-3 px-3 flex items-center justify-between rounded-2 cursor-pointer border-none text-3',
selectedTags.includes(tag.title)
? tag.color
: ' border-gray-1 border-solid transition',
]"
@click="handleSelectTags(tag.title)"
>
{{ tag.title }}
<button
type="button"
class="ml-2 p-1 border-transparent focus:outline-none bg-transparent hover:bg-opacity-30 cursor-pointer"
@click.stop="handleDelete(tag.id)"
>
X
</button>
</div>
<button
v-if="showAddTags"
type="button"
class="h-8 mb-2 mr-3 px-3 border border-none rounded-4 cursor-pointer hover:bg-gray-2"
bg="gray-100"
@click="addTagButton"
>
<i class="i-mdi:tag-plus-outline">加</i>
</button>
<button
v-if="!showAddTags"
type="button"
class="h-8 mb-2 mr-3 px-3 border border-none rounded-4 cursor-pointer hover:bg-gray-2"
bg="gray-100"
@click="showAddTags = !showAddTags"
>
<i class="i-mdi:tag-minus-outline">減</i>
</button>
<button
v-if="!showAddTags"
type="button"
class="h-8 mb-2 mr-3 px-3 border border-none rounded-4 cursor-pointer hover:bg-gray-2 text-[#004AAD]"
bg="gray-100"
@click="saveTag"
>
<i class="i-mdi:tag-check-outline">勾</i>
</button>
<div
v-if="!showAddTags"
:class="[
'w-full h-8 mb-2 mr-3 px-3 flex items-center justify-between rounded-2 cursor-pointer border-none border-gray-1 border-solid transition bg-gray-100 hover:border-gray-2 hover:bg-white',
, newTag.color,
]"
@click="sendValueToParent"
>
<input
v-model="newTag.title"
class="w-full border-none focus:border-b-2 focus:border-blue-500 rounded-none outline-none bg-transparent"
type="text"
/>
<button
type="button"
class="ml-2 pr-1 border-transparent focus:outline-none bg-transparent hover:bg-opacity-30 text-gray-3"
>
<i class="i-mdi:tag-edit-outline">筆</i>
</button>
</div>
<div
v-if="!showAddTags"
class="w-full h-8 mb-2 mr-3 px-3 flex items-center justify-start rounded-2 border-none border-gray-1 border-solid transition bg-gray-1 hover:border-gray-2 hover:bg-white"
>
<div
v-for="color in tagColors"
:key="color"
:class="[
'w-4 h-4 mr-2 rounded-full cursor-pointer border-solid',
color,
newTag.color === color ? 'border-gray-3' : 'border-gray-2',
]"
@click="setColor(color)"
></div>
<button
type="button"
class="ml-10 pr-1 border-transparent focus:outline-none bg-transparent hover:bg-opacity-30 text-gray-3"
>
<i class="i-ic:outline-color-lens">彩</i>
</button>
</div>
</div>
</div>
</template>
補上圖片
謝謝各位讀者們^_^