隨著文章越來越多,就開始有點難找到文章。這時候如果有一個搜尋功能幫我篩選文章列表就太好了。既然這麼想,就來實作吧!
首先,我預計在文章列表標題頁面下放置一個搜尋列,我會傳給他一個 searchValue
作為 model 去共用,宣告其為 ref('')
。然後再透過 computed()
去篩選文章列表,我會檢查文章標題、標籤、日期有沒有符合搜尋列的關鍵字:
<template>
<SearchBar v-model="searchValue" placeholder-text="Search announce" />
...
<li v-for="article in filteredArticles" :key="article._path" class="py-4">
<ListItem :item="article" />
</li>
</template>
<script lang="ts" setup>
import { DateTime } from 'luxon'
const searchValue = ref('')
const filteredArticles = computed(() => {
return articles.filter((post: Post) => {
const tags = post.tags.filter((tag) => !!tag)
const searchContent =
post.title +
tags.map((tag: string) => (tag ? tag.split(' ').join('-') : '')) +
DateTime.fromISO(post.published_at).toFormat('yyyy-LL-dd')
return searchContent.toLowerCase().includes(searchValue.value.toLowerCase())
})
})
</script>
然後製作一個搜尋列元件,並且透過 defineEmit()
來將搜尋列的關鍵字傳回文章列表:
<template>
<div class="relative max-w-lg">
<label>
<span class="sr-only">{{ placeholderText }}</span>
<input
:v-model="modelValue"
:aria-label="placeholderText"
type="text"
:placeholder="*placeholderText*"
class="block w-full rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-900 focus:border-primary-500 focus:ring-primary-500"
@input="$emit('update:modelValue', $event.target.value)"
/>
</label>
<svg
class="absolute right-3 top-3 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</div>
</template>
<script setup lang="ts">
defineProps({
modelValue: {
type: String,
default: '',
},
placeholderText: {
type: String,
default: '',
},
})
defineEmits(['update:modelValue'])
</script>
如此就實作出來了
試著在搜尋列打標題作為關鍵字
試著在搜尋列打日期作為關鍵字