Dev to webs {Coding…}

เรียนรู้การพัฒนาซอฟเวอร์ เพื่อความรู้ที่ยั่งยืน

บทที่ 31: การใช้ Alpine.store


1. ความเข้าใจเกี่ยวกับ Alpine.store

Alpine.store เป็นฟีเจอร์ที่ช่วยให้คุณสามารถแชร์ State ระหว่าง Component ต่าง ๆ ในหน้าเว็บได้

  • Alpine.store ช่วยจัดการ State แบบ Global ซึ่งทำให้ Component หลายตัวสามารถเข้าถึงและอัปเดต State ร่วมกันได้
  • เหมาะสำหรับการจัดการข้อมูลที่ใช้งานร่วมกัน เช่น ธีมของเว็บไซต์, ข้อมูลผู้ใช้, หรือ สถานะการเข้าสู่ระบบ

2. การตั้งค่า Alpine.store

ตัวอย่าง: สร้าง Store สำหรับธีม
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('theme', {
            mode: 'light',
            toggle() {
                this.mode = this.mode === 'light' ? 'dark' : 'light';
            }
        });
    });
</script>

คำอธิบาย:

  • Alpine.store('theme', {...}) สร้าง Store ชื่อ theme เพื่อเก็บสถานะธีม (mode) และฟังก์ชัน toggle() สำหรับสลับธีม

3. การใช้งาน Store ใน Component

ตัวอย่าง: เปลี่ยนธีมด้วย Store
<div x-data>
    <p>Current Theme: <span x-text="$store.theme.mode"></span></p>
    <button @click="$store.theme.toggle()">Toggle Theme</button>
</div>

คำอธิบาย:

  • ใช้ $store.theme.mode เพื่อเข้าถึงค่า mode ใน Store
  • เรียก $store.theme.toggle() เพื่อสลับธีมระหว่าง light และ dark

4. การแชร์ State ระหว่าง Component

ตัวอย่าง: Component หลายตัวแชร์ Store เดียวกัน
<div x-data>
    <p>Theme: <span x-text="$store.theme.mode"></span></p>
</div>

<div x-data>
    <button @click="$store.theme.toggle()">Change Theme</button>
</div>

คำอธิบาย:

  • Component ทั้งสองเข้าถึง Store theme ร่วมกัน
  • เมื่อคลิกปุ่มใน Component ที่สอง, ค่า mode ใน Component ที่หนึ่งจะอัปเดตตาม

5. การใช้งานฟังก์ชันใน Store

ตัวอย่าง: การจัดการ State ซับซ้อน
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('counter', {
            value: 0,
            increment() {
                this.value++;
            },
            decrement() {
                this.value--;
            }
        });
    });
</script>

<div x-data>
    <p>Counter: <span x-text="$store.counter.value"></span></p>
    <button @click="$store.counter.increment()">Increment</button>
    <button @click="$store.counter.decrement()">Decrement</button>
</div>

คำอธิบาย:

  • สร้าง Store ชื่อ counter เพื่อเก็บค่า value และฟังก์ชัน increment() กับ decrement()
  • Component เข้าถึงค่า value และฟังก์ชันจาก Store

6. การใช้ Store กับ Transition หรือ Animation

ตัวอย่าง: ใช้ Store ควบคุมการแสดง/ซ่อน
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('visibility', {
            isVisible: false,
            toggle() {
                this.isVisible = !this.isVisible;
            }
        });
    });
</script>

<div x-data>
    <button @click="$store.visibility.toggle()">Toggle Visibility</button>
    <div x-show="$store.visibility.isVisible" x-transition style="background: lightblue; padding: 10px;">
        <p>This content is toggled by a store.</p>
    </div>
</div>

คำอธิบาย:

  • Store visibility ใช้ควบคุมสถานะการแสดง (isVisible)
  • ปุ่มเรียก $store.visibility.toggle() เพื่อเปลี่ยนสถานะการแสดงผลของข้อความ

7. การใช้ Store ร่วมกับ $watch

ตัวอย่าง: ติดตามค่าที่เปลี่ยนใน Store
<div x-data x-init="$watch('$store.theme.mode', value => console.log(`Theme changed to: ${value}`))">
    <p>Theme: <span x-text="$store.theme.mode"></span></p>
    <button @click="$store.theme.toggle()">Toggle Theme</button>
</div>

คำอธิบาย:

  • $watch('$store.theme.mode', callback) ติดตามการเปลี่ยนแปลงของค่า mode ใน Store theme
  • พิมพ์ข้อความใน Console เมื่อธีมถูกเปลี่ยน

8. การใช้ Store กับ Component ซ้อนกัน

ตัวอย่าง: ใช้ Store ใน Component ย่อย
<div x-data>
    <h1>Parent Component</h1>
    <p>Theme: <span x-text="$store.theme.mode"></span></p>
    <child-component></child-component>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('theme', {
            mode: 'light',
            toggle() {
                this.mode = this.mode === 'light' ? 'dark' : 'light';
            }
        });

        Alpine.data('childComponent', () => ({
            toggleTheme() {
                this.$store.theme.toggle();
            }
        }));
    });
</script>

<div x-data="childComponent">
    <h2>Child Component</h2>
    <button @click="toggleTheme()">Toggle Theme from Child</button>
</div>

คำอธิบาย:

  • Store theme ถูกแชร์ระหว่าง Parent และ Child Component
  • Child Component ใช้ Store เพื่อสลับธีมผ่านฟังก์ชัน toggleTheme()

9. ข้อควรระวังในการใช้ Alpine.store

  1. การตั้งชื่อ Store:
    • ชื่อของ Store ควรมีความหมายและไม่ซ้ำกับชื่ออื่นในโปรเจกต์
  2. การจัดการ State:
    • ระวังการแก้ไข State โดยตรงจาก Component ควรใช้ฟังก์ชันใน Store เพื่อจัดการ
  3. การโหลดข้อมูลครั้งแรก:
    • หากต้องการค่าเริ่มต้นที่ดึงจาก API ควรโหลดข้อมูลก่อนกำหนดค่าใน Store

สรุป

ในบทนี้ คุณได้เรียนรู้วิธีใช้ Alpine.store เพื่อแชร์ State ระหว่าง Component และจัดการข้อมูลที่ใช้งานร่วมกัน ตัวอย่างครอบคลุมการสร้าง Store, การเข้าถึง State และฟังก์ชันใน Store, และการจัดการ State ระหว่าง Component หลายตัว ในบทถัดไป เราจะพูดถึงการจัดการ Event และฟีเจอร์ขั้นสูงอื่น ๆ ใน Alpine.js!