แถบนำทางด้านข้าง
แถบนำทางด้านข้างให้แถบนำทางที่ปรับแต่งได้ซึ่งรวมโลโก้ ลิงก์นำทาง การดำเนินการด่วน และแถบค้นหา

การใช้งานพื้นฐาน
ในการใช้งานคอมโพเนนต์ Sidenav ให้ใช้ไวยากรณ์ต่อไปนี้:
<spr-sidenav>
<template #logo-image>
<img src="[logo_image_path]" alt="logo" />
</template>
</spr-sidenav>ช่อง
โลโก้ภาพที่กำหนดเอง
ช่อง logo-image ช่วยให้คุณสามารถแทรกลงโก้ที่กำหนดเองในแถบนำทางด้านข้างได้ ใช้เทมเพลตต่อไปนี้เพื่อเพิ่มโลโก้:
<template #logo-image>
<img src="[image_path]" alt="logo" />
</template>การรวมคอมโพเนนต์ไอคอน
Design System ให้พร็อพเพอร์ตี้ icon ที่ช่วยให้คุณใช้คอมโพเนนต์ Icon ได้ คุณสามารถใช้คอมโพเนนต์ Icon เพื่อแสดงไอคอนในแถบนำทางด้านข้างได้
ปัจจุบัน Design System ใช้ไลบรารี Iconify เพื่อแสดงไอคอน คุณสามารถใช้ชื่อไอคอน Iconify เพื่อแสดงไอคอนในแถบนำทางด้านข้างได้ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Iconify โปรดดูที่ เอกสาร Iconify
ไอคอนที่กำหนดเอง
ในการใช้ไอคอนที่กำหนดเองสำหรับลิงก์นำทางของคุณ ให้ระบุลิงก์ CDN ไปยังภาพโดยใช้พร็อพเพอร์ตี้ icon สำหรับสถานะที่ใช้งานอยู่ ให้อัปโหลดลิงก์ CDN เวอร์ชันของไอคอนที่มี -fill เพิ่มต่อท้ายก่อนนามสกุลไฟล์ คอมโพเนนต์จะสลับระหว่างไอคอนเริ่มต้นและไอคอนที่ใช้งานอยู่โดยอัตโนมัติตามสถานะนำทาง:
การตั้งชื่อ CDN
เริ่มต้น: https://eco-cdn-prod.azureedge.net/payroll.svg
ใช้งานอยู่: https://eco-cdn-prod.azureedge.net/payroll-fill.svg
<script lang="ts" setup>
const navLinks = ref({
top: [
{
parentLinks: [
{
title: 'Home',
icon: 'https://eco-cdn-prod.azureedge.net/payroll.svg',
},
],
},
],
});
</script>ลิงก์นำทาง
ลิงก์นำทางถูกจัดระเบียบเป็นส่วนที่จัดกลุ่ม โดยแต่ละส่วนประกอบด้วยหมวดหมู่ต่างๆ แต่ละหมวดหมู่มีลิงก์ที่อาจมีเมนูย่อยและเมนูย่อยย่อย
การกำหนดลิงก์นำทางมี 2 ส่วน คือ top และ bottom แต่ละส่วนสามารถมี parentLinks ได้หลายรายการที่แสดงถึงรายการนำทางระดับบนสุด
<template>
<spr-sidenav :nav-links="navLinks">
<template #logo-image>
<img src="@/assets/images/sprout-hr-logo.svg" alt="logo" />
</template>
</spr-sidenav>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const navLinks = ref({
top: [
{
parentLinks: [
{
title: 'Home',
icon: 'ph:house-simple',
menuLinks: [
{
menuHeading: 'Sub Heading 1',
items: [
{
title: 'Dashboard 1',
submenuLinks: [
{
subMenuHeading: 'Sub Heading 1',
items: [
{
title: 'Home 1',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
subMenuHeading: 'Sub Heading 2',
items: [
{
title: 'Home 3',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 4',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'Dashboard 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
],
bottom: [
{
parentLinks: [
{
title: 'Home',
icon: 'ph:house-simple',
menuLinks: [
{
menuHeading: 'Sub Heading 1',
items: [
{
title: 'Dashboard 1',
submenuLinks: [
{
subMenuHeading: 'Sub Heading 1',
items: [
{
title: 'Home 1',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
subMenuHeading: 'Sub Heading 2',
items: [
{
title: 'Home 3',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 4',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'Dashboard 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
],
});
</script>โครงสร้างลิงก์นำทาง
แอตทริบิวต์ nav-links คาดหวังอาร์เรย์ของออบเจกต์ที่กำหนดเมนูนำทาง แต่ละออบเจกต์สามารถมี:
top:คุณสามารถกำหนดลิงก์นำทางระดับบนสุดในส่วนบนของแถบนำทางด้านข้างได้bottom:คุณสามารถกำหนดลิงก์นำทางระดับบนสุดในส่วนล่างของแถบนำทางด้านข้างได้parentLinks:รายการลิงก์นำทางระดับบนสุด แต่ละลิงก์อาจมีพร็อพเพอร์ตี้เพิ่มเติมเช่นtitle,icon,redirectและmenuLinkstitle:ชื่อของแต่ละรายการลิงก์นำทาง เมื่อmenulinksว่างหรือไม่ได้ระบุ ชื่อจะแสดงเมื่อโฮเวอร์ที่ parent linkicon:ไอคอนที่เกี่ยวข้องกับparentLinksเท่านั้น โดยปกติเป็น iconify string (เช่น `ph:home`, `ph:users-three`) ดูเพิ่มเติมได้ที่ Iconifyredirect:URL หรือเส้นทางที่ผู้ใช้จะถูกเปลี่ยนเส้นทางเมื่อคลิกที่รายการนำทาง การเปลี่ยนเส้นทางจะไม่ทำงานหากมีmenuLinksหรือsubmenuLinksopenInNewTab:แฟล็กบูลีนที่ระบุว่าลิงก์จะเปิดในแท็บใหม่หรือไม่isAbsoluteURL:แฟล็กบูลีนที่ระบุว่าลิงก์จะเปิดโดยใช้ href หรือไม่link:URL หรือปลายทางจริงสำหรับรายการนำทาง มักใช้สำหรับการกำหนดเส้นทางภายในหรือลิงก์ไปยังส่วนต่างๆ ของแอปmenuLinks:ปรากฏภายใต้parentLinksรายการนำทาง ลิงก์เมนูเหล่านี้กำหนดส่วนหรือหมวดหมู่เพิ่มเติมภายใต้ parent linksubmenuLinks:ลิงก์ที่ซ้อนอยู่ภายใต้menuLinksเปิดใช้งานการนำทางหลายระดับ ลิงก์เหล่านี้เป็นการแบ่งย่อยเพิ่มเติมหรือรายการลูกภายใต้แต่ละส่วนmenuLinkshidden:แฟล็กบูลีนที่ระบุว่ารายการการดำเนินการด่วนควรถูกซ่อนหรือไม่
นี่คือโครงสร้างสำหรับแอตทริบิวต์ nav-links:
{
top: [
{
parentLinks: [
{
title: <String>,
icon: <String>,
hidden: <Boolean>,
redirect: {
openInNewTab: <Boolean>,
isAbsoluteURL: <Boolean>,
link: <String>,
},
menuLinks: [
{
menuHeading: <String>,
items: [
{
title: <String>,
hidden: <Boolean>,
redirect: {
openInNewTab: <Boolean>,
isAbsoluteURL: <Boolean>,
link: <String>,
},
submenuLinks: [
{
subMenuHeading: <String>,
items: [
{
title: <String>,
hidden: <Boolean>,
redirect: {
openInNewTab: <Boolean>,
isAbsoluteURL: <Boolean>,
link: <String>,
},
},
],
},
],
},
],
}
],
},
],
},
],
bottom: [
{
parentLinks: [
{
title: <String>,
icon: <String>,
redirect: {
openInNewTab: <Boolean>,
isAbsoluteURL: <Boolean>,
link: <String>,
},
menuLinks: [
{
menuHeading: <String>,
items: [
{
title: <String>,
redirect: {
openInNewTab: <Boolean>,
isAbsoluteURL: <Boolean>,
link: <String>,
},
submenuLinks: [
{
subMenuHeading: <String>,
items: [
{
title: <String>,
redirect: {
openInNewTab: <Boolean>,
isAbsoluteURL: <Boolean>,
link: <String>,
},
},
],
},
],
},
],
}
],
},
],
},
]
}การนำทางที่ใช้งานอยู่
พร็อพเพอร์ตี้ active-nav ช่วยให้คุณสามารถไฮไลต์สถานะที่ใช้งานอยู่ทั่วทั้งระดับต่างๆ ของการนำทาง (parent, menu, และ submenu) เพื่อรวมเข้ากับคอมโพเนนต์ Sidenav ของคุณ ตรวจสอบให้แน่ใจว่าค่าของการนำทางที่ใช้งานอยู่ตรงกับชื่อของรายการที่เกี่ยวข้องในโครงสร้างการนำทางที่ใช้งานอยู่ของคุณ และส่งออบเจกต์การนำทางที่ใช้งานอยู่พร้อมกับ props อื่นๆ ของคุณ
นี่คือตัวอย่างวิธีการใช้งานพร็อพเพอร์ตี้การนำทางที่ใช้งานอยู่:
<template>
<spr-sidenav :active-nav="activeNav" :nav-links="navLinks">
<template #logo-image>
<img src="@/assets/images/sprout-hr-logo.svg" alt="logo" />
</template>
</spr-sidenav>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const activeNav = ref({
parentNav: 'HR Home',
menu: 'HR Dashboard',
submenu: 'Leave Management',
});
const navLinks = ref({
top: [
{
parentLinks: [
{
title: 'Home',
icon: 'ph:house-simple',
menuLinks: [
{
menuHeading: 'Sub Heading 1',
items: [
{
title: 'Dashboard 1',
submenuLinks: [
{
subMenuHeading: 'Sub Heading 1',
items: [
{
title: 'Home 1',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
subMenuHeading: 'Sub Heading 2',
items: [
{
title: 'Home 3',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 4',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'Dashboard 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
],
bottom: [
{
parentLinks: [
{
title: 'Home',
icon: 'ph:house-simple',
menuLinks: [
{
menuHeading: 'Sub Heading 1',
items: [
{
title: 'Dashboard 1',
submenuLinks: [
{
subMenuHeading: 'Sub Heading 1',
items: [
{
title: 'Home 1',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
subMenuHeading: 'Sub Heading 2',
items: [
{
title: 'Home 3',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Home 4',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'Dashboard 2',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
],
});
</script>การจัดการการเปลี่ยน URL ด้วยตนเอง
เมื่อผู้ใช้เปลี่ยน URL ด้วยตนเอง พร็อพเพอร์ตี้ active-nav จะไม่อัปเดตโดยอัตโนมัติ สิ่งนี้เป็นเพราะ active-nav โดยปกติจะถูกกำหนดผ่านการคลิกที่ไอคอนนำทาง และการพิมพ์ URL ด้วยตนเองไม่ได้ทริกเกอร์ลอจิกเดียวกัน
เพื่อจัดการสิ่งนี้ คุณสามารถใช้ Router Meta Field เพิ่มออบเจกต์ activeNav ภายในฟิลด์ meta ของเส้นทาง และเฝ้าดูการเปลี่ยนเส้นทาง จากนั้นกำหนดออบเจกต์ activeNav จาก meta ของเส้นทางไปยังพร็อพเพอร์ตี้ active-nav ของ sidenav ของคุณ
const routes = [ { path: 'workflows', name: 'workflows', meta:{ activeNav: { parentNav: 'Flow', menu: '', submenu: '', }
} }, ]<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const activeNav = ref({
parentNav: 'หน้าแรก HR',
menu: 'แดชบอร์ด HR',
submenu: 'การจัดการการลา',
});
router.beforeEach((to) => {
if (to.meta.activeNav) {
activeNav.value = to.meta.activeNav;
}
});
</script>การใช้ข้อมูล API (isNavApi)
เมื่อ isNavApi ถูกตั้งค่าเป็น true คอมโพเนนต์ sidenav คาดหวังข้อมูลนำทางในรูปแบบอื่นที่มาจาก API โดยตรง รูปแบบนี้รวมพร็อพเพอร์ตี้เพิ่มเติมเช่น id, code, position, order, และ attributes
<template>
<spr-sidenav :nav-links="apiNavLinks" :is-nav-api="true" :active-nav="activeNav" @get-navlink-item="handleNavClick">
<template #logo-image>
<img src="/path/to/logo.png" alt="logo" />
</template>
</spr-sidenav>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
// ตัวอย่างโครงสร้างข้อมูล API
const apiNavLinks = ref({
top: [
{
id: '135c50eb-3dbb-4e4a-b45a-9f58b4c0921f',
code: null,
label: 'Dashboard',
url: 'https://ecohub-qa.ecoapp-qa.sprout.ph/dashboard',
icon: 'ph:house-simple',
children: [],
position: 'top',
order: 1,
attributes: null,
groupId: '1',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
{
id: '8ee582db-afa7-4c6b-a80a-503eb7057cda',
code: null,
label: 'App Management',
url: null,
icon: 'ph:shapes',
children: [
{
id: '03b895a8-9de5-4f0e-b19b-4d965c99cd7d',
code: null,
label: 'Marketplace',
url: 'https://market.sprout.ph/',
icon: null,
children: [],
position: 'top',
order: 2,
attributes: null,
groupId: null,
groupName: null,
parentMenuId: '8ee582db-afa7-4c6b-a80a-503eb7057cda',
isNewTab: true,
},
],
position: 'top',
order: 2,
attributes: null,
groupId: '1',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
{
id: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
code: null,
label: 'Payroll',
url: null,
icon: 'https://eco-cdn-prod.azureedge.net/payroll.svg',
children: [
{
id: null,
code: null,
label: 'Payroll Runs',
url: 'https://ecohub-qa-payroll.sprout.ph/Client/Payrolls.aspx',
icon: null,
children: [],
position: null,
order: 1,
attributes: [],
groupId: null,
groupName: null,
parentMenuId: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
isNewTab: null,
},
{
id: null,
code: null,
label: 'Setup',
url: '',
icon: null,
children: [
{
id: null,
code: null,
label: 'Company Profile',
url: 'https://ecohub-qa-payroll-next-qa.sprout.ph/#/global/company-profile',
icon: null,
children: [],
position: null,
order: 1,
attributes: [],
groupId: null,
groupName: 'COMPANY',
parentMenuId: null,
isNewTab: null,
},
{
id: null,
code: null,
label: 'Department',
url: 'https://ecohub-qa-payroll-next-qa.sprout.ph/#/global/department',
icon: null,
children: [],
position: null,
order: 2,
attributes: [],
groupId: null,
groupName: 'COMPANY',
parentMenuId: null,
isNewTab: null,
},
// ... more nested items
],
position: null,
order: 2,
attributes: [],
groupId: null,
groupName: null,
parentMenuId: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
isNewTab: null,
},
],
position: 'top',
order: 6,
attributes: null,
groupId: '2',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
],
bottom: [], // รายการนำทางด้านล่างจะเป็นไปตามโครงสร้างเดียวกัน
});
const activeNav = ref({
parentNav: 'HR Home',
menu: 'HR Dashboard',
submenu: 'Leave Management',
});
const handleNavClick = (route) => {
console.log(route);
};
const handleSearch = (search) => {
console.log(search);
};
const handleNotifications = (notifications) => {
console.log(notifications);
};
const handleRequest = (request) => {
console.log(request);
};
const userMenu = ref({
name: 'John Doe',
email: '[email protected]',
profileImage: 'https://media.sproutsocial.com/uploads/2022/06/profile-picture.jpeg',
items: [
{
title: 'โปรไฟล์ของฉัน',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'นโยบายความเป็นส่วนตัว',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'เงื่อนไขการให้บริการ',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'ออกจากระบบ',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
});
</script>ตัวอย่างแบบเต็ม
นี่คือตัวอย่างแบบเต็มของวิธีการใช้งานคอมโพเนนต์ Sidenav: สลับไปที่โหลดเพื่อดูสถานะการโหลด
Lorem Ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi quis est in quam efficitur tempor. Integer blandit egestas risus, non consequat massa rhoncus eget. Donec commodo luctus diam, egestas scelerisque justo fermentum vel. Morbi vestibulum quis arcu sit amet sollicitudin. Vestibulum fringilla et risus at porttitor. Sed at augue non nunc tempus sagittis quis a magna. Mauris lacinia neque massa, sed fermentum libero dignissim et. Vivamus faucibus aliquet arcu, a viverra leo vehicula at. Aliquam ut turpis vitae mi scelerisque blandit in non diam. Nulla molestie, ipsum id interdum auctor, sem odio bibendum turpis, sed accumsan nisl nunc id lacus. Vestibulum ante eros, accumsan sit amet mollis et, fermentum at est. In hac habitasse platea dictumst.
Morbi posuere orci arcu, efficitur maximus ante eleifend ut. Aliquam suscipit finibus dui a pellentesque. Praesent vel nulla turpis. Nullam gravida diam vitae lectus consectetur euismod. Pellentesque ut leo lorem. Integer nec feugiat lorem. Nam sodales nibh ut varius rutrum. Donec vel gravida purus. Aliquam dictum, elit a maximus scelerisque, lorem odio facilisis odio, volutpat interdum diam mauris vitae massa. Nunc ornare ligula eu diam bibendum finibus. Nullam maximus convallis ornare. Curabitur dolor magna, euismod at dui pretium, feugiat aliquet mi. Nullam tincidunt sapien ante, ac efficitur eros lobortis a.
Nulla lacinia fermentum fermentum. Sed lorem leo, pulvinar laoreet augue vel, rhoncus sollicitudin enim. Donec vel viverra neque. Ut at ante a massa commodo consequat quis tristique diam. Duis erat ipsum, pellentesque nec urna vitae, sodales pretium dui. Quisque ullamcorper consequat lorem. Duis bibendum dapibus velit, sed pulvinar risus ornare nec. Morbi sagittis sit amet libero quis rutrum. Curabitur finibus ullamcorper nisl nec blandit. Vestibulum placerat ex leo, vel efficitur risus vehicula et. Nam non nibh dui. Sed eu pellentesque ligula, id semper massa. Sed eu nunc fringilla, posuere diam a, porttitor eros.
Nulla faucibus eros eget convallis ullamcorper. Nam nec vehicula ipsum, ut pulvinar diam. Suspendisse sit amet metus rhoncus, pulvinar arcu quis, tincidunt lectus. Proin a mi quam. Aenean vitae massa dignissim lacus ultrices faucibus. Etiam ut bibendum quam. Vestibulum ut placerat neque. Aliquam laoreet congue lacus a semper. Suspendisse sed elementum diam. Nullam faucibus urna iaculis, suscipit arcu sit amet, elementum ligula. Duis at velit sed arcu condimentum porta ut id sem. Donec et odio ut purus viverra semper.
Integer quam magna, semper sed vehicula eu, maximus ut mauris. Quisque non dolor ornare, pulvinar ex id, imperdiet velit. Suspendisse potenti. In dignissim nibh ut tortor interdum accumsan a sit amet ante. Morbi vehicula odio nulla, ac fermentum augue congue at. Nulla volutpat interdum ex et aliquet. Duis pharetra tellus sit amet nisl congue molestie.
<template>
<spr-sidenav
:quick-actions="quickActions"
has-search
:active-nav="activeNav"
:nav-links="navLinks"
:notification-count="5"
:request-count="10"
:user-menu="userMenu"
@get-navlink-item="handleGetNavLinkItem"
@search="handleSearch"
@notifications="handleNotifications"
>
<template #logo-image>
<img src="@/assets/images/sprout-hr-logo.svg" alt="logo" />
</template>
</spr-sidenav>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import SprSidenav from '@/components/sidenav/sidenav.vue';
const quickActions = ref([
{
menuHeading: 'Sub Heading 1',
items: [
{
title: 'Leave Request',
description: 'Lorem ipsum dolor sit amet consectetur.',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Onboarding Request',
description: 'Seamlessly onboard new employees into your Sprout ecosystem',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Certificate of Employee',
description: 'Lorem ipsum dolor sit amet consectetur. ',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
menuHeading: 'Sub Heading 2',
items: [
{
title: 'ReadyWage',
description: 'Request Form',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Create Workflow',
description: 'Access your hard-earned salary in advance',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Create Something 1',
description: 'Lorem ipsum dolor sit amet consectetur.',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Create Something 2',
description: 'Lorem ipsum dolor sit amet consectetur.',
icon: 'ph:house-simple',
iconBgColor: 'purple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
]);
const activeNav = ref({
parentNav: 'HR Home',
menu: 'HR Dashboard',
submenu: 'Leave Management',
});
const navLinks = ref({
top: [
{
parentLinks: [
{
title: 'HR Home',
icon: 'ph:house-simple',
attributes: [{ name: 'lozenge', value: { label: 'New', tone: 'success' } }],
menuLinks: [
{
menuHeading: 'HR Management',
items: [
{
title: 'HR Dashboard',
submenuLinks: [
{
subMenuHeading: 'Employee Overview',
items: [
{
title: 'Employee List',
redirect: {},
},
{
title: 'Attendance',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
subMenuHeading: 'Benefits',
items: [
{
title: 'Leave Management',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'Compensation',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
attributes: [{ name: 'lozenge', value: { label: 'New', tone: 'success' } }],
},
],
},
],
attributes: [{ name: 'lozenge', value: { label: 'New', tone: 'success' } }],
},
{
title: 'HR Analytics',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'HR Employees',
icon: 'ph:users-three',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
parentLinks: [
{
title: 'HR Payroll',
icon: 'ph:leaf',
menuLinks: [
{
menuHeading: 'Payroll Management',
items: [
{
title: 'Payroll Processing',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Payroll Reports',
submenuLinks: [
{
subMenuHeading: 'Government Reports',
items: [
{
title: 'SSS Report',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'PhilHealth Report',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Pag-IBIG Report',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
{
menuHeading: 'HR Setup',
items: [
{
title: 'HR Settings',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'HR Employee Records',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'HR Finance',
icon: 'ph:currency-rub',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
menuLinks: [
{
menuHeading: 'Finance Operations',
items: [
{
title: 'Payroll Budget',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Expense Tracking',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Financial Reports',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'HR Vehicles',
icon: 'ph:wallet',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
menuLinks: [
{
menuHeading: 'HR Fleet',
items: [
{
title: 'Company Cars',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'Fleet Management',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
],
bottom: [
{
parentLinks: [
{
title: 'HR Gallery',
icon: 'ph:address-book',
menuLinks: [
{
menuHeading: 'HR Resources',
items: [
{
title: 'HR Dashboard',
submenuLinks: [
{
subMenuHeading: 'HR Team',
items: [
{
title: 'HR Directory',
redirect: {},
},
{
title: 'HR Attendance',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
{
subMenuHeading: 'HR Benefits',
items: [
{
title: 'HR Leaves',
redirect: {
openInNewTab: false,
isAbsoluteURL: true,
link: 'https://www.google.com/',
},
},
{
title: 'HR Compensation',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
{
title: 'HR Analytics',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
},
],
},
{
parentLinks: [
{
title: 'HR Resources',
icon: 'ph:alien',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'HR News',
icon: 'ph:align-left',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
},
],
});
const handleGetNavLinkItem = (route) => {
console.log(route);
};
const handleSearch = (search) => {
console.log(search);
};
const handleNotifications = (notifications) => {
console.log(notifications);
};
const handleRequest = (request) => {
console.log(request);
};
const userMenu = ref({
name: 'John Doe',
email: '[email protected]',
profileImage: 'https://media.sproutsocial.com/uploads/2022/06/profile-picture.jpeg',
items: [
{
title: 'โปรไฟล์ของฉัน',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'นโยบายความเป็นส่วนตัว',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'เงื่อนไขการให้บริการ',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
{
title: 'ออกจากระบบ',
icon: 'ph:house-simple',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/',
},
},
],
});
</script>ตัวอย่างแบบเต็มด้วยข้อมูล API (isNavApi)
นี่คือการใช้งานแบบเต็มตัวอย่างโดยใช้คอมโพเนนต์ sidenav กับ isNavApi: true และโครงสร้างข้อมูล API จริง:
ตัวอย่างการนำทางที่ขับเคลื่อนด้วย API
ตัวอย่างนี้แสดงให้เห็นว่าคอมโพเนนต์ sidenav ทำงานอย่างไรกับโครงสร้างข้อมูล API จริง การนำทางถูกสร้างขึ้นแบบไดนามิกจากการตอบสนอง API รองรับลำดับชั้นที่ซ้อนกันอย่างซับซ้อนด้วยหลายระดับของเมนูและเมนูย่อย
ข้อมูล API รวมพร็อพเพอร์ตี้เช่น groupId, groupName, parentMenuId, และ isNewTab ซึ่งให้ฟังก์ชันการทำงานเพิ่มเติมสำหรับการจัดระเบียบและจัดการรายการนำทาง โครงสร้างนี้มักใช้ในแอปพลิเคชันระดับองค์กรที่การนำทางต้องการความยืดหยุ่นและปรับแต่งได้
สังเกตว่าส่วน Payroll แสดงการซ้อนที่ลึกด้วย Setup → Company Profile และ Department items ในขณะที่ส่วน App Management แสดงลิงก์ภายนอกที่เปิดในแท็บใหม่ ความยืดหยุ่นนี้ช่วยให้ระบบนำทางที่ครอบคลุมที่สามารถรองรับสถาปัตยกรรมแอปพลิเคชันต่างๆ
<template>
<spr-sidenav
:nav-links="apiNavData"
:is-nav-api="true"
:active-nav="activeNav"
:notification-count="12"
:request-count="3"
:user-menu="userMenu"
has-search
@get-navlink-item="handleNavClick"
@search="handleSearch"
@notifications="handleNotifications"
@requests="handleRequests"
>
<template #logo-image>
<img src="@/assets/images/sprout-hr-logo.svg" alt="logo" />
</template>
</spr-sidenav>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import SprSidenav from '@/components/sidenav/sidenav.vue';
// โครงสร้างข้อมูล API จริงตัวอย่าง
const apiNavData = ref({
top: [
{
id: '135c50eb-3dbb-4e4a-b45a-9f58b4c0921f',
code: null,
label: 'Dashboard',
url: 'https://ecohub-qa.ecoapp-qa.sprout.ph/dashboard',
icon: 'ph:house-simple',
children: [],
position: 'top',
order: 1,
attributes: null,
groupId: '1',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
{
id: '8ee582db-afa7-4c6b-a80a-503eb7057cda',
code: null,
label: 'App Management',
url: null,
icon: 'ph:shapes',
children: [
{
id: '03b895a8-9de5-4f0e-b19b-4d965c99cd7d',
code: null,
label: 'Marketplace',
url: 'https://market.sprout.ph/',
icon: null,
children: [],
position: 'top',
order: 2,
attributes: null,
groupId: null,
groupName: null,
parentMenuId: '8ee582db-afa7-4c6b-a80a-503eb7057cda',
isNewTab: true,
},
{
id: '04b895a8-9de5-4f0e-b19b-4d965c99cd8e',
code: null,
label: 'Extensions',
url: 'https://extensions.sprout.ph/',
icon: null,
children: [],
position: 'top',
order: 3,
attributes: null,
groupId: null,
groupName: null,
parentMenuId: '8ee582db-afa7-4c6b-a80a-503eb7057cda',
isNewTab: true,
},
],
position: 'top',
order: 2,
attributes: null,
groupId: '1',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
{
id: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
code: null,
label: 'Payroll',
url: null,
icon: 'https://eco-cdn-prod.azureedge.net/payroll.svg',
children: [
{
id: 'payroll-runs-001',
code: null,
label: 'Payroll Runs',
url: 'https://ecohub-qa-payroll.sprout.ph/Client/Payrolls.aspx',
icon: null,
children: [],
position: null,
order: 1,
attributes: [],
groupId: null,
groupName: null,
parentMenuId: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
isNewTab: false,
},
{
id: 'payroll-setup-001',
code: null,
label: 'Setup',
url: '',
icon: null,
children: [
{
id: 'company-profile-001',
code: null,
label: 'Company Profile',
url: 'https://ecohub-qa-payroll-next-qa.sprout.ph/#/global/company-profile',
icon: null,
children: [],
position: null,
order: 1,
attributes: [],
groupId: null,
groupName: 'COMPANY',
parentMenuId: 'payroll-setup-001',
isNewTab: false,
},
{
id: 'department-001',
code: null,
label: 'Department',
url: 'https://ecohub-qa-payroll-next-qa.sprout.ph/#/global/department',
icon: null,
children: [],
position: null,
order: 2,
attributes: [],
groupId: null,
groupName: 'COMPANY',
parentMenuId: 'payroll-setup-001',
isNewTab: false,
},
{
id: 'employees-001',
code: null,
label: 'Employees',
url: 'https://ecohub-qa-payroll-next-qa.sprout.ph/#/global/employees',
icon: null,
children: [],
position: null,
order: 3,
attributes: [],
groupId: null,
groupName: 'WORKFORCE',
parentMenuId: 'payroll-setup-001',
isNewTab: false,
},
],
position: null,
order: 2,
attributes: [],
groupId: null,
groupName: null,
parentMenuId: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
isNewTab: false,
},
{
id: 'payroll-reports-001',
code: null,
label: 'Reports',
url: null,
icon: null,
children: [
{
id: 'sss-report-001',
code: null,
label: 'SSS Reports',
url: 'https://ecohub-qa-payroll.sprout.ph/Reports/SSS',
icon: null,
children: [],
position: null,
order: 1,
attributes: [],
groupId: null,
groupName: 'GOVERNMENT',
parentMenuId: 'payroll-reports-001',
isNewTab: false,
},
{
id: 'philhealth-report-001',
code: null,
label: 'PhilHealth Reports',
url: 'https://ecohub-qa-payroll.sprout.ph/Reports/PhilHealth',
icon: null,
children: [],
position: null,
order: 2,
attributes: [],
groupId: null,
groupName: 'GOVERNMENT',
parentMenuId: 'payroll-reports-001',
isNewTab: false,
},
],
position: null,
order: 3,
attributes: [],
groupId: null,
groupName: null,
parentMenuId: 'e9a88315-ecf7-49ea-82d9-0c6a5fd2a9e2',
isNewTab: false,
},
],
position: 'top',
order: 6,
attributes: null,
groupId: '2',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
],
bottom: [
{
id: 'settings-001',
code: null,
label: 'Settings',
url: '/settings',
icon: 'ph:gear',
children: [],
position: 'bottom',
order: 1,
attributes: null,
groupId: '99',
groupName: null,
parentMenuId: null,
isNewTab: false,
},
{
id: 'help-001',
code: null,
label: 'Help & Support',
url: 'https://help.sprout.ph',
icon: 'ph:question',
children: [],
position: 'bottom',
order: 2,
attributes: null,
groupId: '99',
groupName: null,
parentMenuId: null,
isNewTab: true,
},
],
});
const activeNav = ref({
parentNav: 'HR Home',
menu: 'HR Dashboard',
submenu: 'Leave Management',
});
const userMenu = ref({
name: 'John Doe',
email: '[email protected]',
profileImage: 'https://media.sproutsocial.com/uploads/2022/06/profile-picture.jpeg',
items: [
{
title: 'โปรไฟล์ของฉัน',
icon: 'ph:user',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/profile',
},
},
{
title: 'การตั้งค่าบัญชี',
icon: 'ph:gear',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/settings',
},
},
{
title: 'นโยบายความเป็นส่วนตัว',
icon: 'ph:shield-check',
redirect: {
openInNewTab: true,
isAbsoluteURL: true,
link: 'https://sprout.ph/privacy',
},
},
{
title: 'ออกจากระบบ',
icon: 'ph:sign-out',
redirect: {
openInNewTab: false,
isAbsoluteURL: false,
link: '/logout',
},
},
],
});
// Event handlers
const handleNavClick = (navItem) => {
console.log('Navigation clicked:', navItem);
// อัปเดตการนำทางที่ใช้งานอยู่ตามโครงสร้าง API
if (navItem.parentMenuId === null) {
// การนำทางระดับบนสุด
activeNav.value = {
parentNav: navItem.label,
menu: '',
submenu: '',
};
} else {
// จัดการลอจิกนำทางที่ซ้อนกันที่นี่
console.log('Nested navigation:', navItem);
}
// จัดการการนำทาง URL
if (navItem.url) {
if (navItem.isNewTab) {
window.open(navItem.url, '_blank');
} else {
// ใช้ router ของคุณเพื่อนำทาง
// router.push(navItem.url);
console.log('Navigate to:', navItem.url);
}
}
};
const handleSearch = (searchTerm) => {
console.log('Search:', searchTerm);
// ใช้ฟังก์ชันการค้นหา
};
const handleNotifications = () => {
console.log('Notifications clicked');
// จัดการการแจ้งเตือน
};
const handleRequests = () => {
console.log('Requests clicked');
// จัดการคำขอ
};
</script>การอ้างอิง API
Props
พร็อพเพอร์ตี้ต่อไปนี้พร้อมใช้งานสำหรับคอมโพเนนต์ Sidenav:
| ชื่อ | คำอธิบาย | ประเภท | ค่าเริ่มต้น |
quick-actions | แสดงเมนูการดำเนินการด่วนที่มีรายการที่จัดกลุ่ม แต่ละการดำเนินการด่วนสามารถมีชื่อ คำอธิบาย ไอคอน และข้อมูลการเปลี่ยนเส้นทาง | QuickAction[] | [] |
has-search | ควบคุมการมองเห็นของปุ่มค้นหาในแถบนำทางด้านข้าง | boolean | false |
active-nav | ตั้งค่าสถานะที่ใช้งานอยู่สำหรับการนำทาง รวมถึงการนำทาง parent, menu และ submenu ใช้เพื่อไฮไลต์รายการนำทางที่ใช้งานอยู่ | { parentNav: string; menu: string; submenu: string } | { parentNav: '', menu: '', submenu: '' } |
nav-links | กำหนดโครงสร้างนำทางด้วยส่วนบนและล่าง แต่ละส่วนประกอบด้วย parent links, menu links และ submenu links สำหรับการนำทางแบบลำดับชั้น | NavLinks | { top: [], bottom: [] } |
notification-count | แสดงแบดจ์ตัวนับการแจ้งเตือนบนไอคอนการแจ้งเตือน ใช้ 0 เพื่อแสดงไอคอนโดยไม่มีแบดจ์หรือ string ว่างเพื่อซ่อนโดยสิ้นเชิง | string | number | '' |
request-count | แสดงแบดจ์ตัวนับคำขอบนไอคอนคำขอ ใช้ 0 เพื่อแสดงไอคอนโดยไม่มีแบดจ์หรือ string ว่างเพื่อซ่อนโดยสิ้นเชิง | string | number | '' |
user-menu | แสดงอวาตาร์ผู้ใช้ที่ด้านล่างของแถบนำทางด้านข้างพร้อมกับเมนูได้ เมนูผู้ใช้สามารถมีรายการต่างๆ เช่น โปรไฟล์ การตั้งค่า และออกจากระบบ | UserMenu | false | false |
is-notif-active | ควบคุมว่าปุ่มการแจ้งเตือนจะปรากฏในสถานะที่ใช้งานอยู่ด้วยการจัดรูปแบบไอคอนที่เต็มหรือไม่ | boolean | false |
is-request-active | ควบคุมว่าปุ่มคำขอจะปรากฏในสถานะที่ใช้งานอยู่ด้วยการจัดรูปแบบไอคอนที่เต็มหรือไม่ | boolean | false |
is-nav-api | เมื่อตั้งค่าเป็น true คอมโพเนนต์จะคาดหวังข้อมูลนำทางในรูปแบบ API และจะแปลงเป็นรูปแบบภายใน มีประโยชน์เมื่อรวมเข้ากับ API หลังบ้าน | boolean | false |
Events
Events ต่อไปนี้ถูกปล่อยออกมาจากคอมโพเนนต์ Sidenav:
| ชื่อ | คำอธิบาย | พารามิเตอร์ |
get-navlink-item | ถูกปล่อยออกมาเมื่อคลิกลิงก์นำทาง ส่งคืนออบเจกต์รายการที่คลิกพร้อมข้อมูลการเปลี่ยนเส้นทางและสถานะนำทางที่ใช้งานอยู่ Event นี้ให้จุดเชื่อมต่อเพื่อจัดการการนำทาง router ของคุณ | objectItem: object - รายการนำทางที่คลิกพร้อมข้อมูลการเปลี่ยนเส้นทางและสถานะนำทางที่ใช้งานอยู่ |
search | ถูกปล่อยออกมาเมื่อคลิกปุ่มค้นหา สามารถใช้เพื่อเรียกใช้ฟังก์ชันการค้นหาในแอปพลิเคชัน parent | event: string - มี string ค่า 'search-triggered' |
notifications | ถูกปล่อยออกมาเมื่อคลิกปุ่มการแจ้งเตือน สามารถใช้เพื่อเรียกใช้แผงการแจ้งเตือนหรือฟังก์ชันในแอปพลิเคชัน parent | event: string - มี string ค่า 'notifications-triggered' |
requests | ถูกปล่อยออกมาเมื่อคลิกปุ่มคำขอ สามารถใช้เพื่อเรียกใช้แผงคำขอหรือฟังก์ชันในแอปพลิเคชัน parent | event: string - มี string ค่า 'requests-triggered' |
Slots
| ชื่อ | คำอธิบาย |
logo-image | Slot สำหรับแทรกรูปภาพโลโก้ที่ด้านบนของ sidenav โดยปกติใช้กับแท็ก <img> พื้นที่โลโก้มีสไตล์ที่กำหนดไว้ล่วงหน้าสำหรับการแสดงโลโก้ขนาดเล็ก (24px × 24px) อย่างเหมาะสม |
Types
คอมโพเนนต์ Sidenav ใช้ประเภทข้อมูลที่ซับซ้อนต่อไปนี้:
QuickAction
type QuickAction = {
menuHeading: string;
items: QuickActionItem[];
};
type QuickActionItem = {
title: string;
description: string;
icon: string;
iconBgColor: string; // ค่า: 'green' หรือ 'purple'
redirect: Redirect;
hidden: boolean;
};NavLinks
type NavLinks = {
top: { parentLinks: ParentLinkItem[] }[];
bottom: { parentLinks: ParentLinkItem[] }[];
};
type ParentLinkItem = {
title: string;
icon: string;
link?: string;
redirect?: Redirect;
menuLinks: MenuLink[];
submenuLinks?: SubmenuLink[];
hidden?: boolean;
attributes?: Attributes[]; // สำหรับ metadata เพิ่มเติมเช่น lozenges
};
type MenuLink = {
menuHeading: string;
items: MenuLinkItem[] | ParentLinkItem[];
};
type MenuLinkItem = {
title: string;
hidden: boolean;
redirect: Redirect;
submenuLinks: SubmenuLink[];
attributes?: Attributes[]; // สำหรับ metadata เพิ่มเติมเช่น lozenges
};
type SubmenuLink = {
subMenuHeading: string;
items: SubmenuLinkItem[] | ParentLinkItem[];
};
type SubmenuLinkItem = {
title: string;
hidden: boolean;
redirect: Redirect;
attributes?: Attributes[]; // สำหรับ metadata เพิ่มเติมเช่น lozenges
};
type Redirect = {
openInNewTab: boolean;
isAbsoluteURL: boolean;
link: string;
};ประเภทข้อมูล API
เมื่อใช้ isNavApi: true ประเภทต่อไปนี้จะใช้สำหรับการนำทางที่มาจาก API:
type NavAPILinks = {
top: { parentLinks: NavItem[] }[];
bottom: { parentLinks: NavItem[] }[];
};
interface NavItem {
id: string;
groupId: string;
label: string;
icon?: string | null;
url?: string | null;
isNewTab?: boolean;
children?: NavItem[] | null;
groupName?: string | null;
hidden?: boolean;
attributes?: Attributes[] | null;
position?: string;
order?: number;
parentMenuId?: string | null;
}
type Attributes = {
name: string;
value: unknown | string | number | boolean | AttrLozenge;
};
type AttrLozenge = {
label: string;
tone?: string; // ค่าที่ถูกต้อง: 'danger', 'information', 'plain', 'pending', 'success', 'neutral', 'caution'
};UserMenu
type UserMenu = {
name: string;
email: string;
profileImage: string;
items: UserMenuItem[];
};
type UserMenuItem = {
title: string;
icon: string;
hidden: boolean;
redirect: Redirect;
};