ตัวกรอง
คอมโพเนนต์ Filter เป็นโซลูชันการกรองที่หลากหลายและทรงพลังที่ออกแบบมาสำหรับสถานการณ์การกรองข้อมูลที่ซับซ้อน มันรองรับทั้งฟังก์ชันการค้นหาง่ายๆ และตัวเลือกการกรองขั้นสูงด้วยการกรองตามหมวดหมู่ ทำให้เหมาะสำหรับแอปพลิเคชันที่ต้องการความสามารถในการสำรวจข้อมูลที่แข็งแกร่ง
คุณสมบัติ
- การกรองแบบเลือกหลายรายการ: เลือกตัวเลือกหลายรายการจากเมนูดรอปดาวน์ด้วยตัวควบคุมช่องทำเครื่องหมาย
- เมนูตัวกรองขั้นสูง: สร้างการรวมตัวกรองที่ซับซ้อนด้วยการกรองตามหมวดหมู่ผ่านระบบเมนูซ้อน
- การเลื่อนไม่สิ้นสุด: รองรับในตัวสำหรับโหลดชุดข้อมูลขนาดใหญ่แบบเพิ่มขึ้นเพื่อประสิทธิภาพที่ดีขึ้น
- ฟังก์ชันการค้นหา: ความสามารถในการค้นหาสำหรับทั้งตัวเลือกหลักและตัวเลือกตัวกรองขั้นสูง
- การรวม API ภายนอก: การรวมอย่างราบรื่นกับ API การค้นหาและตัวกรองภายนอก
- รองรับอวตาร: แสดงอวตารผู้ใช้หรือตัวระบุภาพอื่นๆ ควบคู่ไปกับตัวเลือกตัวกรอง
- UI ที่ปรับแต่งได้: ระบบสล็อตที่ครอบคลุมสำหรับปรับแต่งลักษณะและพฤติกรรม
- การเข้าถึง: การนำทางด้วยแป้นพิมพ์และรองรับ ARIA สำหรับการเข้าถึงที่ดีขึ้น
- การจัดการข้อผิดพลาด: รองรับสถานะข้อผิดพลาดและข้อความช่วยเหลือในตัวสำหรับสถานการณ์การตรวจสอบ
- การออกแบบที่ตอบสนอง: ปรับให้เข้ากับขนาดหน้าจอและความกว้างคอนเทนเนอร์ที่แตกต่างกัน
การใช้งานพื้นฐาน
<template>
<spr-filter v-model="selectedOptions" v-model:search="searchValue" :options="options" label="Search" hasAvatar />
</template>
<script setup>
import { ref } from 'vue';
const options = ref([
{ column: '', isSelected: false, text: 'sample 1', value: 'sample1' },
{ column: '', isSelected: false, text: 'sample 2', value: 'sample2' },
{ column: '', isSelected: false, text: 'sample 3', value: 'sample3' },
{ column: '', isSelected: false, text: 'sample 4', value: 'sample4' },
{ column: '', isSelected: false, text: 'sample 5', value: 'sample5' },
]);
const selectedOptions = ref([]);
const searchValue = ref('');
</script>ตัวกรองได้
<template>
<spr-filter
v-model="selectedOptions1"
v-model:search="searchValue1"
:options="options1"
label="Search"
:filterMenu="filterMenuList1"
:filterData="filterMenuOptions1"
filterable
/>
</template>
<script setup>
const options = ref([
{ column: '', isSelected: false, text: 'sample 1', value: 'sample1' },
{ column: '', isSelected: false, text: 'sample 2', value: 'sample2' },
{ column: '', isSelected: false, text: 'sample 3', value: 'sample3' },
{ column: '', isSelected: false, text: 'sample 4', value: 'sample4' },
{ column: '', isSelected: false, text: 'sample 5', value: 'sample5' },
]);
const filterMenuList = ref([
{ count: 0, isFilterVisible: false, columnName: 'Employee Type', field: 'employeeType' },
{ count: 0, isFilterVisible: false, columnName: 'Department', field: 'department' },
{ count: 0, isFilterVisible: false, columnName: 'Location', field: 'location' },
{ count: 0, isFilterVisible: false, columnName: 'Region', field: 'region' },
{ count: 0, isFilterVisible: false, columnName: 'Job Level', field: 'jobLevel' },
]);
const filterMenuOptions = [
{ column: 'location', isSelected: false, text: 'sample 1', value: 'sample1' },
{ column: 'location', isSelected: false, text: 'sample 2', value: 'sample2' },
{ column: 'location', isSelected: false, text: 'sample 3', value: 'sample3' },
{ column: 'location', isSelected: false, text: 'sample 4', value: 'sample4' },
];
const selectedOptions = ref([]);
const searchValue = ref('');
</script>เลิกเลือก
ตัวอย่างนี้แสดงวิธีการลบตัวเลือกที่เลือกออกจากภายนอกคอมโพเนนต์
<template>
<div class="spr-space-y-3">
<div class="spr-flex spr-gap-2">
<div v-for="selected in selectedOptions2">
<spr-button hasIcon size="small" tone="danger" variant="secondary" @click="removeSelected(selected.value)">
{{ selected.value }}
<Icon icon="ph:trash" />
</spr-button>
</div>
</div>
<spr-filter
v-model="selectedOptions2"
v-model:search="searchValue2"
id="search-filter"
:deselected="deselected"
:options="options"
label="Search"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { Icon } from '@iconify/vue';
import SprButton from '@/components/button/button.vue';
const options = ref([
{ column: '', isSelected: false, text: 'sample 1', value: 'sample1' },
{ column: '', isSelected: false, text: 'sample 2', value: 'sample2' },
{ column: '', isSelected: false, text: 'sample 3', value: 'sample3' },
{ column: '', isSelected: false, text: 'sample 4', value: 'sample4' },
{ column: '', isSelected: false, text: 'sample 5', value: 'sample5' },
]);
const selectedOptions2 = ref([]);
const searchValue2 = ref('');
const deselected = ref('');
const removeSelected = (removeSelected) => {
deselected.value = removeSelected;
};
</script>สถานะข้อผิดพลาด
<template>
<div class="spr-space-y-3">
<spr-filter
v-model="selectedOptions2"
v-model:search="searchValue2"
id="search-filter-display-text"
:deselected="deselected"
:options="options"
helper-text="This is helper text!!"
/>
<spr-filter
v-model="selectedOptions2"
v-model:search="searchValue2"
id="search-filter-error"
:deselected="deselected"
:options="options"
error
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { Icon } from '@iconify/vue';
import SprButton from '@/components/button/button.vue';
const options = ref([
{ column: '', isSelected: false, text: 'sample 1', value: 'sample1' },
{ column: '', isSelected: false, text: 'sample 2', value: 'sample2' },
{ column: '', isSelected: false, text: 'sample 3', value: 'sample3' },
{ column: '', isSelected: false, text: 'sample 4', value: 'sample4' },
{ column: '', isSelected: false, text: 'sample 5', value: 'sample5' },
]);
const selectedOptions2 = ref([]);
const searchValue2 = ref('');
</script>การอ้างอิง API
พร็อพส์
| ชื่อ | คำอธิบาย | ประเภท | ค่าเริ่มต้น | จำเป็น |
|---|---|---|---|---|
modelValue | ค่าตัวกรองที่เลือก รองรับการผูก v-model สำหรับการจัดการสถานะการเลือก | Array | String | [] | ไม่ |
options | รายการตัวเลือกตัวกรอง แต่ละตัวเลือกควรมีโครงสร้าง: { column: string, isSelected: boolean, text: string, value: string, subtext?: string, avatar?: string } | Array | [] | ใช่ |
label | ป้ายสำหรับฟิลด์อินพุตตัวกรอง | String | '' | ไม่ |
placeholder | ข้อความตัวยึดตำแหน่งสำหรับฟิลด์อินพุตตัวกรอง | String | '' | ไม่ |
disabled | ปิดใช้งานอินพุตตัวกรอง ป้องกันการโต้ตอบของผู้ใช้ | Boolean | false | ไม่ |
filterable | เปิดใช้งานเมนูตัวกรองขั้นสูงด้วยการกรองตามคอลัมน์ | Boolean | false | ไม่ |
id | ตัวระบุเฉพาะสำหรับคอมโพเนนต์ตัวกรอง ใช้สำหรับการเข้าถึงและการจัดการ DOM | String | 'spr-filter' | ไม่ |
filterMenu | รายการหมวดหมู่เมนูตัวกรองขั้นสูง แต่ละรายการควรมี: { columnName: string, field: string, isFilterVisible?: boolean, count?: number } | Array | [] | ไม่ |
filterData | ข้อมูลสำหรับเมนูตัวกรองขั้นสูง โครงสร้างคล้ายกับ options แต่โดยเฉพาะสำหรับตัวกรองขั้นสูง | Array | [] | ไม่ |
loading | ระบุว่ามีเมนูตัวกรองขั้นสูงอยู่ในสถานะการโหลดหรือไม่ | Boolean | false | ไม่ |
filling | ระบุว่ามีดรอปดาวน์ตัวกรองหลักอยู่ในสถานะการโหลดหรือไม่ | Boolean | false | ไม่ |
search | คำค้นหาสำหรับตัวกรองหลัก รองรับการผูก v-model:search | String | '' | ไม่ |
searchFilter | คำค้นหาสำหรับเมนูตัวกรองขั้นสูง รองรับการผูก v-model:searchFilter | String | '' | ไม่ |
width | ความกว้างของคอมโพเนนต์ตัวกรอง ยอมรับค่าความกว้าง CSS (px, %, rem, etc.) | String | '100%' | ไม่ |
deselected | ค่าของตัวเลือกตัวกรองที่ถูกเลิกเลือก ใช้เพื่อลบการเลือกจากภายนอกคอมโพเนนต์ | String | '' | ไม่ |
hasSearchApi | เปิดใช้งานการรวม API การค้นหาภายนอกสำหรับตัวกรองหลัก เมื่อเป็นจริง การกรองภายในจะถูกปิดใช้งาน | Boolean | false | ไม่ |
hasAvatar | เปิดใช้งานการแสดงอวตารสำหรับตัวเลือกตัวกรอง ใช้พร็อพส์ avatar ในตัวเลือกเพื่อให้ URL รูปภาพ | Boolean | false | ไม่ |
helperText | ข้อความช่วยเหลือที่แสดงใต้คอมโพเนนต์ตัวกรอง มีประโยชน์สำหรับให้บริบทหรือคำแนะนำเพิ่มเติม | String | '' | ไม่ |
error | เปิดใช้งานการจัดสไตล์สถานะข้อผิดพลาดสำหรับตัวกรอง ใช้กับรูปแบบการตรวจสอบ | Boolean | false | ไม่ |
hasAdvancedFilterApi | เปิดใช้งานการรวม API การค้นหาภายนอกสำหรับเมนูตัวกรองขั้นสูง เมื่อเป็นจริง การกรองภายในจะถูกปิดใช้งาน | Boolean | false | ไม่ |
อีเวนต์
| ชื่อ | ประเภทเพย์โหลด | คำอธิบาย | การใช้งาน |
|---|---|---|---|
getFilterData | String | ถูกทริกเกอร์เมื่อดึงข้อมูลตัวกรองสำหรับคอลัมน์เฉพาะในตัวกรองขั้นสูง เพย์โหลดคือชื่อฟิลด์คอลัมน์ | @getFilterData="handleGetFilterData" |
update:modelValue | Array | อัปเดตค่าตัวกรองที่เลือก ใช้ภายในสำหรับการผูก v-model | จัดการโดยการผูก v-model |
update:search | String | อัปเดตคำค้นหาสำหรับตัวกรองหลัก ใช้ภายในสำหรับการผูก v-model:search | จัดการโดยการผูก v-model:search |
update:searchFilter | String | อัปเดตคำค้นหาสำหรับเมนูตัวกรองขั้นสูง ใช้ภายในสำหรับการผูก v-model:searchFilter | จัดการโดยการผูก v-model:searchFilter |
selectedFilter | Array | ปล่อยตัวเลือกตัวกรองที่เลือกจากเมนูตัวกรองขั้นสูง ประกอบด้วยตัวเลือกที่เลือกทั้งหมดในทุกคอลัมน์ | @selectedFilter="handleSelectedFilter" |
infiniteScrollTrigger | Boolean | ถูกทริกเกอร์เมื่อการเลื่อนไม่สิ้นสุดถูกเปิดใช้งานสำหรับตัวกรองหลัก ใช้สำหรับโหลดข้อมูลเพิ่มเติมในสถานการณ์ที่มีการแบ่งหน้า | @infiniteScrollTrigger="loadMoreOptions" |
infiniteScrollFilterTrigger | String | ถูกทริกเกอร์เมื่อการเลื่อนไม่สิ้นสุดถูกเปิดใช้งานสำหรับตัวกรองขั้นสูง เพย์โหลดคือคอลัมน์ปัจจุบันที่กำลังเลื่อน | @infiniteScrollFilterTrigger="loadMoreFilterOptions" |
สล็อต
| ชื่อสล็อต | คำอธิบาย | การใช้งาน |
|---|---|---|
default | สล็อตสำหรับปรับแต่งฟิลด์อินพุตตัวกรอง แทนที่คอมโพเนนต์อินพุตเริ่มต้นทั้งหมด | |
loading | สล็อตสำหรับแสดงสถานะการโหลดปรับแต่งในเมนูตัวกรองขั้นสูง ใช้เมื่อโหลดตัวเลือกตัวกรอง | |
empty | สล็อตสำหรับแสดงสถานะว่างเปล่าปรับแต่งในเมนูตัวกรองขั้นสูง ใช้เมื่อไม่พบตัวเลือกตัวกรอง | |
loading-state | สล็อตสำหรับแสดงสถานะการโหลดปรับแต่งในดรอปดาวน์ตัวกรองหลัก ใช้เมื่อโหลดตัวเลือกหลัก | |
empty-state | สล็อตสำหรับแสดงสถานะว่างเปล่าปรับแต่งในดรอปดาวน์ตัวกรองหลัก ใช้เมื่อไม่มีตัวเลือกตรงกับการค้นหา | |
คุณสมบัติขั้นสูง
การเลื่อนไม่สิ้นสุด
คอมโพเนนต์รองรับการเลื่อนไม่สิ้นสุดสำหรับทั้งตัวกรองหลักและเมนูตัวกรองขั้นสูง คุณสมบัตินี้มีประโยชน์โดยเฉพาะสำหรับจัดการชุดข้อมูลขนาดใหญ่ที่ควรโหลดแบบเพิ่มขึ้นเพื่อปรับปรุงประสิทธิภาพ
การใช้งาน
- การเลื่อนไม่สิ้นสุดตัวกรองหลัก:
- ฟังอีเวนต์
infiniteScrollTriggerซึ่งถูกปล่อยเมื่อผู้ใช้เลื่อนไปที่ด้านล่างของดรอปดาวน์ตัวกรองหลัก - โหลดข้อมูลเพิ่มเติมและผนวกเข้ากับอาร์เรย์
options
- ฟังอีเวนต์
<spr-filter v-model="selectedOptions" :options="options" @infiniteScrollTrigger="loadMoreOptions" />
<script setup>
const loadMoreOptions = () => {
// โหลดข้อมูลเพิ่มเติมจาก API ของคุณ
const newOptions = await fetchMoreOptions(page.value++);
options.value = [...options.value, ...newOptions];
};
</script>- การเลื่อนไม่สิ้นสุดตัวกรองขั้นสูง:
- ฟังอีเวนต์
infiniteScrollFilterTriggerซึ่งให้ฟิลด์คอลัมน์ที่กำลังเลื่อน - โหลดข้อมูลเพิ่มเติมสำหรับคอลัมน์นั้นโดยเฉพาะ
- ฟังอีเวนต์
<spr-filter
v-model="selectedOptions"
:options="options"
:filter-menu="filterMenu"
:filter-data="filterData"
filterable
@infiniteScrollFilterTrigger="loadMoreFilterOptions"
/>
<script setup>
const loadMoreFilterOptions = (column) => {
// โหลดตัวเลือกตัวกรองเพิ่มเติมสำหรับคอลัมน์เฉพาะ
const newFilterOptions = await fetchMoreFilterOptions(column, page.value++);
filterData.value = [...filterData.value, ...newFilterOptions];
};
</script>การรวม API การค้นหาภายนอก
คอมโพเนนต์ตัวกรองรองรับการรวมกับ API การค้นหาภายนอกสำหรับทั้งตัวกรองหลักและเมนูตัวกรองขั้นสูง สิ่งนี้ช่วยให้การกรองและการค้นหาแบบฝั่งเซิร์ฟเวอร์
API การค้นหาตัวกรองหลัก
เปิดใช้งานพร็อพส์ hasSearchApi เพื่อใช้ API ภายนอกสำหรับกรองตัวเลือกหลัก เมื่อเปิดใช้งาน คอมโพเนนต์จะไม่กรองตัวเลือกภายใน แต่พึ่งพา API ภายนอกเพื่อให้ผลลัพธ์ที่กรอง
<spr-filter
v-model="selectedOptions"
v-model:search="searchValue"
:options="options"
:has-search-api="true"
@update:search="handleSearchChange"
/>
<script setup>
const handleSearchChange = async (query) => {
// เรียก API ภายนอกของคุณด้วยคำค้นหา
options.value = await searchApi(query);
};
</script>API การค้นหาตัวกรองขั้นสูง
เปิดใช้งานพร็อพส์ hasAdvancedFilterApi เพื่อใช้ API ภายนอกสำหรับการค้นหาเมนูตัวกรองขั้นสูง ทำงานคล้ายกับ API การค้นหาหลัก แต่สำหรับเมนูตัวกรองขั้นสูง
<spr-filter
v-model="selectedOptions"
:filter-menu="filterMenu"
:filter-data="filterData"
:has-advanced-filter-api="true"
filterable
@update:searchFilter="handleAdvancedSearch"
/>
<script setup>
const handleAdvancedSearch = async (query) => {
// เรียก API ภายนอกของคุณด้วยคำค้นหาและคอลัมน์ปัจจุบัน
filterData.value = await searchAdvancedApi(query, selectedColumn.value);
};
</script>รองรับอวตาร
คอมโพเนนต์ตัวกรองสามารถแสดงอวตารควบคู่ไปกับตัวเลือกตัวกรองเพื่อให้สัญญาณภาพหรือการแสดงตัวแทนผู้ใช้
เปิดใช้งานพร็อพส์ hasAvatar เพื่อแสดงอวตารสำหรับตัวเลือกตัวกรอง ให้พร็อพส์ avatar ในแต่ละออบเจ็กต์ตัวเลือก:
<spr-filter v-model="selectedOptions" :options="optionsWithAvatars" has-avatar />
<script setup>
const optionsWithAvatars = ref([
{
column: '',
isSelected: false,
text: 'John Doe',
value: 'john',
avatar: 'https://example.com/avatars/john.jpg',
},
{
column: '',
isSelected: false,
text: 'Jane Smith',
value: 'jane',
avatar: 'https://example.com/avatars/jane.jpg',
},
]);
</script>หากไม่ได้ให้ URL อวตาร คอมโพเนนต์จะแสดงอวตารแบบอักษรย่อโดยใช้ตัวอักษรแรกของพร็อพส์ text
การเลิกเลือกภายนอก
คอมโพเนนต์ตัวกรองอนุญาตให้เลิกเลือกตัวเลือกจากภายนอกคอมโพเนนต์ ซึ่งมีประโยชน์สำหรับการใช้งานอินเทอร์เฟซการเลือกปรับแต่งเช่น ชิปส์หรือป้ายภายนอก
<template>
<div class="spr-flex spr-gap-2">
<div v-for="selected in selectedOptions">
<spr-button @click="removeSelected(selected.value)">
{{ selected.text }}
<Icon icon="ph:x" />
</spr-button>
</div>
</div>
<spr-filter v-model="selectedOptions" :options="options" :deselected="deselectedOption" />
</template>
<script setup>
const selectedOptions = ref([]);
const deselectedOption = ref('');
const removeSelected = (value) => {
deselectedOption.value = value;
// รีเซ็ตค่าที่ถูกเลิกเลือกหลังจากถูกประมวลผล
setTimeout(() => {
deselectedOption.value = '';
}, 100);
};
</script>การใช้ผลิตภัณฑ์
ผลิตภัณฑ์ Sprout เหล่านี้ใช้คอมโพเนนต์ตัวกรอง: