คอมโพเนนต์ปฏิทิน
คอมโพเนนต์ Calendar เป็นปฏิทินรายสัปดาห์ที่ครอบคลุมและปรับแต่งได้ ออกแบบมาสำหรับการจัดตารางเวลาพนักงานและการจัดการ มันให้อินเทอร์เฟซที่มีคุณสมบัติครบถ้วนสำหรับการดูและโต้ตอบกับตารางเวลาพนักงาน รวมถึงการสนับสนุน:
- การนำทางวันที่รายสัปดาห์ด้วยการควบคุมที่ใช้งานง่าย
- รายชื่อพนักงานพร้อมข้อมูลโปรไฟล์และการติดตามชั่วโมงการทำงาน
- การแสดงกะหลายรายการสำหรับแต่ละวันพร้อมรายละเอียด
- การสนับสนุนวันหยุดและประเภทกะแบบกำหนดเอง
- การเลื่อนแบบไม่สิ้นสุดสำหรับรายชื่อพนักงานขนาดใหญ่
- การปรับแต่งสถานะว่างเปล่า
- สถานะการโหลดและตัวโหลดโครงกระดูก
- การออกแบบที่ตอบสนองด้วยการจัดการการล้นที่เหมาะสม
การใช้งาน
ตัวอย่างพื้นฐาน
Mar - Apr 2026
Employee Name | 29 SUN | 30 MON | 31 TUE | 01 WED | 02 THU | 03 FRI | 04 SAT |
|---|---|---|---|---|---|---|---|
TW Theresa Webb Senior UX Researcher 40/48 HRS | |||||||
KM Kathryn Murphy Interaction Designer 35/48 HRS | |||||||
KM Kathryn Murphy Interaction Designer 35/48 HRS | |||||||
KM Kathryn Murphy Interaction Designer 35/48 HRS | |||||||
No List Found | |||||||
vue
<template>
<SprCalendar
v-model:search="searchEmployee"
v-model:selected-cell="selectedCell"
v-model:selected-company="selectedCompany"
v-model:selected-department="selectedDepartment"
v-model:selected-branch="selectedBranch"
:employees="employees"
:initial-date="initialDate"
:company-options="companyOptions"
:department-options="departmentOptions"
:branch-options="branchOptions"
/>
</template>
<script setup lang="ts">
import SprCalendar from '@/components/calendar/calendar.vue';
import { ref } from 'vue';
const initialDate = new Date();
const searchEmployee = ref();
const selectedCompany = ref('');
const selectedDepartment = ref('');
const selectedBranch = ref('');
const selectedCell = ref({
employeeId: '',
date: '',
schedule: null,
});
const employees = [
{
id: 1,
name: 'Theresa Webb',
position: 'Senior UX Researcher',
avatar: '',
highlight: true,
hoursWorked: 40,
hoursTarget: 48,
schedule: {
'2025-05-05': [{ type: 'restday' }],
'2025-05-06': [{ startTime: '09:00AM', endTime: '06:00PM', location: 'Office A', type: 'Standard Day Shift' }],
'2025-05-07': [{ startTime: '09:00AM', endTime: '06:00PM', location: 'Office A', type: 'Standard Day Shift' }],
'2025-05-13': [{ startTime: '09:00AM', endTime: '06:00PM', location: 'Office A', type: 'Standard Day Shift' }],
// ...other dates
},
},
{
id: 2,
name: 'Kathryn Murphy',
position: 'Interaction Designer',
avatar: '',
highlight: true,
hoursWorked: 35,
hoursTarget: 48,
schedule: {
'2025-05-05': [{ type: 'restday' }],
'2025-05-08': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
'2025-05-10': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
'2025-05-13': [
{ startTime: '10:00AM', endTime: '06:00PM', location: 'Office a', type: 'Morning Shift' },
{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' },
{ startTime: '10:00AM', endTime: '08:00PM', location: 'Office c', type: 'Morning Shift' },
{ startTime: '10:00AM', endTime: '09:00PM', location: 'Office d', type: 'Morning Shift' },
],
// ...other dates
},
},
{
id: 3,
name: 'Kathryn Murphy',
position: 'Interaction Designer',
avatar: '',
highlight: true,
hoursWorked: 35,
hoursTarget: 48,
schedule: {
'2025-05-01': [{ type: 'restday' }],
'2025-05-02': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
// ...other dates
},
},
{
id: 4,
name: 'Kathryn Murphy',
position: 'Interaction Designer',
avatar: '',
highlight: true,
hoursWorked: 35,
hoursTarget: 48,
schedule: {
'2025-05-12': [{ type: 'restday' }],
'2025-05-15': [{ startTime: '10:00AM', endTime: '07:00PM', location: 'Office B', type: 'Morning Shift' }],
// ...other dates
},
},
];
const companyOptions = [
{ text: 'All Companies', value: 'all' },
{ text: 'Company A', value: 'company-a' },
{ text: 'Company B', value: 'company-b' },
];
const departmentOptions = [
{ text: 'All Departments', value: 'all' },
{ text: 'Design', value: 'design' },
{ text: 'Development', value: 'development' },
];
const branchOptions = [
{ text: 'All Branches', value: 'all' },
{ text: 'Branch A', value: 'branch-a' },
{ text: 'Branch B', value: 'branch-b' },
];
</script>คุณสมบัติ
การเลื่อนแบบไม่สิ้นสุด
ปฏิทินรองรับการเลื่อนแบบไม่สิ้นสุดสำหรับการโหลดข้อมูลพนักงานเพิ่มเติม:
- เรียกใช้โดยอัตโนมัติเมื่อเลื่อนใกล้ด้านล่าง (เกณฑ์ 50px)
- ปล่อยเหตุการณ์
loadMoreเมื่อควรโหลดข้อมูลเพิ่มเติม - รักษาประสบการณ์การเลื่อนที่ราบรื่นด้วยการเว้นระยะที่เหมาะสม
ตัวอย่างการจัดการการเลื่อนแบบไม่สิ้นสุด:
vue
<template>
<SprCalendar @load-more="handleLoadMore" :employees="employees" :loading="isLoading" />
</template>
<script setup>
const handleLoadMore = async () => {
isLoading.value = true;
// โหลดพนักงานเพิ่มเติมที่นี่
await loadMoreEmployees();
isLoading.value = false;
};
</script>API Reference
Props
| ชื่อ | คำอธิบาย | ประเภท | ค่าเริ่มต้น |
|---|---|---|---|
| employees | อาร์เรย์ของข้อมูลพนักงานที่จะแสดงในปฏิทิน รวมถึงข้อมูลตารางเวลา | Array | [] |
| initialDate | วันที่เริ่มต้นที่จะแสดงในปฏิทิน ปฏิทินจะแสดงสัปดาห์ที่มีวันที่นี้ | Date | วันที่ปัจจุบัน |
| loading | ควบคุมว่าจะแสดงตัวบ่งชี้การโหลดหรือไม่ โดยปกติใช้ระหว่างการดึงข้อมูล | boolean | false |
| companyOptions | อาร์เรย์ของตัวเลือกสำหรับดรอปดาวน์ตัวกรองบริษัท | Array<{text: string, value: string}> | [] |
| departmentOptions | อาร์เรย์ของตัวเลือกสำหรับดรอปดาวน์ตัวกรองแผนก | Array<{text: string, value: string}> | [] |
| branchOptions | อาร์เรย์ของตัวเลือกสำหรับดรอปดาวน์ตัวกรองสาขา | Array<{text: string, value: string}> | [] |
| emptyState | การกำหนดค่าสำหรับสถานะว่างเปล่าที่แสดงเมื่อไม่มีพนักงานที่จะแสดง | Object | สถานะว่างเปล่าเริ่มต้น |
Events
| ชื่อ | คำอธิบาย | พารามิเตอร์ |
|---|---|---|
| loadMore | ถูกปล่อยออกมาเมื่อผู้ใช้เลื่อนใกล้ด้านล่างของปฏิทิน (ภายใน 50px) บ่งชี้ว่าควรโหลดข้อมูลพนักงานเพิ่มเติม ใช้สำหรับการนำการเลื่อนแบบไม่สิ้นสุดไปใช้ | - |
| onCellClick | ถูกปล่อยออกมาหากเซลล์ปฏิทินถูกคลิก พารามิเตอร์ประกอบด้วย employeeId วันที่ และข้อมูลกะสำหรับเซลล์ที่คลิก | (data: SelectedShift) |
| update:firstLastDayOfWeek | ถูกปล่อยออกมาหากช่วงสัปดาห์ที่มองเห็นเปลี่ยนแปลง ไม่ว่าจะผ่านการนำทางหรือการเริ่มต้น วันที่ถูกจัดรูปแบบเป็น 'YYYY-MM-DD' | (range: { firstDay: string, lastDay: string }) |
| update:sort | ถูกปล่อยออกมาหากลำดับการเรียงเปลี่ยนแปลงโดยการคลิกไอคอนเรียง ค่าจะเป็น 'asc', 'desc', หรือ '' (สตริงว่างสำหรับไม่มีการเรียง) | (value: string) |
| update:search | ถูกปล่อยออกมาหากคำค้นหาเปลี่ยนแปลง ใช้สำหรับการผูก v-model | (value: string) |
| update:selectedCell | ถูกปล่อยออกมาหากเซลล์ถูกเลือก ใช้สำหรับการผูก v-model ของ prop selectedCell | (data: SelectedShift) |
| update:selectedCompany | ถูกปล่อยออกมาหากการเลือกตัวกรองบริษัทเปลี่ยนแปลง ใช้สำหรับการผูก v-model | (value: string) |
| update:selectedDepartment | ถูกปล่อยออกมาหากการเลือกตัวกรองแผนกเปลี่ยนแปลง ใช้สำหรับการผูก v-model | (value: string) |
| update:selectedBranch | ถูกปล่อยออกมาหากการเลือกตัวกรองสาขาเปลี่ยนแปลง ใช้สำหรับการผูก v-model | (value: string) |
| onClickEmptyButton | ถูกปล่อยออกมาหากปุ่มสถานะว่างเปล่าถูกคลิก สามารถใช้เพื่อเรียกการดำเนินการเช่นการเพิ่มพนักงานใหม่ | - |
Slots
| ชื่อ | คำอธิบาย | ตัวอย่าง | props (ข้อมูลสล็อต) |
|---|---|---|---|
| filter | สล็อตสำหรับปรับแต่งส่วนตัวกรองเหนือปฏิทิน สามารถใช้เพื่อเพิ่มตัวกรองหรือการควบคุมแบบกำหนดเอง | | |
| loading | สล็อตสำหรับปรับแต่งสถานะการโหลดที่แสดงระหว่างการดึงข้อมูล | | |
| empty-state | สล็อตสำหรับปรับแต่งสถานะว่างเปล่าที่แสดงเมื่อไม่มีพนักงานที่จะแสดง โดยค่าเริ่มต้น ใช้คอมโพเนนต์ SprEmptyState | | |
| copy | สล็อตสำหรับปรับแต่งการดำเนินการคัดลอกที่แสดงเมื่อไม่มีพนักงานที่จะแสดง โดยค่าเริ่มต้น ใช้คอมโพเนนต์ SprCopy | | { employeeId: string, date: Date, shift: { startTime?: string, endTime?: string, location?: string, type: string } } |
| cell | สล็อตสำหรับปรับแต่งเนื้อหาของเซลล์ปฏิทิน | | { employeeId: string, date: Date, shift: { startTime?: string, endTime?: string, location?: string, type: string } } |