สำหรับการใช้งานใน Vue 3 (Composition API) หลักการจะคล้ายกับ React แต่เราจะเปลี่ยนจาก useRef และ useEffect มาใช้ ref และ Lifecycle Hooks ของ Vue อย่าง onMounted และ onBeforeUnmount แทนครับ
นี่คือตัวอย่างการเขียนแบบจัดเต็มที่ครอบคลุมทั้งการสร้าง, การใช้ซ้ำ (Reused) , การอัปเดต และการล้างหน่วยความจำครับ
UserTable.vue
<template>
<div class="table-wrapper">
<div class="controls">
<button @click="refreshData">Refresh Data</button>
<button @click="clearTableFilters">Clear Filters</button>
</div>
<div ref="tableElement"></div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import TabulatorPlus from './TabulatorPlus';
// นำเข้า CSS พื้นฐาน
import "tabulator-tables/dist/css/tabulator.min.css";
// 1. รับ Props จากภายนอก
const props = defineProps ({
tableData: {
type: Array,
required: true
}
}) ;
// 2. กำหนดตัวแปรสำหรับ DOM และ Instance
const tableElement = ref (null) ; // เก็บ reference ของ HTML Element
const tabulatorInstance = ref (null) ; // เก็บ Instance ของ Tabulator (Reused Instance) // 3. การสร้างตาราง (Initialize) เมื่อ Component Mount
onMounted ( () => {
if (tableElement.value) {
tabulatorInstance.value = new TabulatorPlus (tableElement.value, {
data: props.tableData,
columns: [
{ title: "Name", field: "name", width: 200 },
{ title: "Age", field: "age" },
{ title: "Location", field: "location" },
],
}, "vue-user-settings") ; // storageKey สำหรับ persistence
}
}) ;
// 4. การ Refresh ข้อมูล (เมื่อ Props เปลี่ยนแปลง) watch ( () => props.tableData, (newData) => {
if (tabulatorInstance.value) {
// ใช้ .setData () เพื่ออัปเดตข้อมูลเดิม แทนการสร้างตารางใหม่ (ดีต่อ Performance) tabulatorInstance.value.setData (newData) ;
}
}, { deep: true }) ;
// 5. วิธีเรียกใช้ Method ภายใน Instance (Reused Instance) const refreshData = () => {
if (tabulatorInstance.value) {
// เช่น สั่งวาดตารางใหม่เพื่อให้ขนาดพอดีกับ Container
tabulatorInstance.value.redraw (true) ;
}
};
const clearTableFilters = () => {
if (tabulatorInstance.value) {
tabulatorInstance.value.clearFilter (true) ;
}
};
// 6. การล้างข้อมูล (Unmount) onBeforeUnmount ( () => {
if (tabulatorInstance.value) {
console.log ("Destroying Tabulator Instance...") ;
// ทำลาย Instance เพื่อป้องกัน Memory Leak
tabulatorInstance.value.destroy () ;
tabulatorInstance.value = null;
}
}) ;
</script>
<style scoped>
.table-wrapper {
padding: 1rem;
}
.controls {
margin-bottom: 1rem;
display: flex;
gap: 10px;
}
/* คุณสามารถเพิ่ม CSS เพื่อแต่งตารางที่นี่ได้ */
:deep (.tabulator) {
border-radius: 4px;
}
</style>
คำอธิบายการทำงาน
- Reused Instance: เราใช้
const tabulatorInstance = ref (null)เพื่อเก็บตัว Instance ไว้ตลอดอายุของ Component ทำให้เราสามารถเรียกใช้ Method ของ Tabulator (เช่น.setData (),.redraw (),.getFilters ()) ได้จากทุกฟังก์ชันใน<script setup> - Refresh ข้อมูล: ใช้
watchคอยดูการเปลี่ยนแปลงของprops.tableDataหากข้อมูลเปลี่ยน เราจะส่งข้อมูลใหม่เข้าตารางทันทีผ่าน.setData ()โดยไม่ต้องทำลายและสร้างตารางใหม่ให้หน้าจอกระพริบ - Unmount & Cleanup: สำคัญมากสำหรับ Single Page Application (SPA) เราใช้
onBeforeUnmountเพื่อสั่ง.destroy ()ตารางเดิมทิ้ง เพื่อคืนค่าหน่วยความจำและล้าง Event Listeners ที่ค้างอยู่ในระบบ - CSS Scoping: ใน Vue คุณสามารถใช้
:deep (.tabulator)ในส่วน<style scoped>เพื่อเจาะเข้าไปแต่งสไตล์ของตาราง Tabulator ได้โดยไม่ไปกระทบตารางอื่นในโปรเจกต์
ทิป (Pro-Tip)
หากคุณใช้ Vue 3 แนะนำให้ใช้ shallowRef แทน ref สำหรับเก็บ tabulatorInstance เพราะ Tabulator เป็น Object ขนาดใหญ่ที่มีความซับซ้อนสูง การให้ Vue เข้าไปทำ Dependency Tracking (Deep Reactivity) กับมันอาจทำให้ Performance ตกได้ครับ
import { shallowRef } from 'vue';
const tabulatorInstance = shallowRef (null) ; // เร็วกว่า ref ปกติในกรณีนี้
อ่านเพิ่มเติม