มาทำความรู้จัก Vuex ORM กันดีกว่า
Table of Contents
ผมเชื่อ Vue developer หลายๆคนคงจะเคยได้ใช้งาน Vuex กันอยู่บ้าง และผมก็เชื่อว่าหลายคนคงหงุดหงิดกับการที่ต้องมาคอยใช้ this.$store.dispatch()
เพราะมันไม่สวยงามเลย แต่เราก็ต้องยอมแลกเพราะมันทำให้เราจัดการ state ของข้อมูลได้ แต่ปัญหาเหล่านี้จะหมดไปถ้าคุณได้ลองใช้ Vuex-ORM
Vuex-ORM คืออะไร #
Vuex ถือกำเนิดขึ้นมาเพื่อใช้จัดการกับ state ทั้งหลายใน app ของเราไม่ว่าจะเป็น store, action หรือ mutation ผมเป็นคนนึงที่ขาด Vuex ถ้าจะต้องทำ **Vue Application **แล้วต้องมาจัดการอะไรพวกนี้เองหรือไม่จัดการมันเลยปล่อยมันอยู่ตาม view หรือ component กระจัดกระจาย ตอนแก้ผมคงปวดหัวแน่นอน แต่ถึงแม้มันจะเทพอย่างไรก็ตาม มันก็ต้องแลกด้วยพิธีและขั้นตอนที่ก็จะทำ code มันดูยุบยับหน่อย โดยเฉพาะมือใหม่หลายคนแค่เริ่มใช้ก็งงแล้ว
Vuex-ORM จึงได้คลานตามกันออกมา โดยเราจะยังคงความเจ๋งของ Vuex ไว้แล้วเสริมด้วยความเป็น ORM
ORM: object-relational mapping
พอเสริมความเป็น ORM เข้ามาแล้วมันทำให้ code นั้นเขียนง่ายและอ่านง่าย มอง object ที่เข้ามาใน store ให้เป็น Model สามารถทำ CRUD ได้เหมือน database โดยไม่ต้องเขียน code เพิ่มด้วยไงล่ะ (ทำไมมันดีจัง ทำไมมันดีกว่าชาวบ้านเขา!) ใครยังนึกภาพไม่ออกเดี๋ยวผมมีตัวอย่าง
วิธีจัดการแบบเดิม #
ตามปกติเวลาเราจะใช้ Vuex ถ้าเราอยากทำ app Todo list เราก็คงต้องเขียนอะไรประมาณนี้ใช่ไหมครับ
ที่ store/index.js ประกาศใน state และสร้าง actions และ mutations function ประมาณนี้
store: {
state: { todos: [] },
actions: {
toggleStatus({ commit, state }, todoId) {
const todo = state.todos.find(todo => {
return todo.id === id
});
commit(SET_TODO_STATUS, { id: todoId, status: !todo.done});
}
},
mutations: {
SET_TODO_STATUS(state, payload) {
const todo = state.todos.find(todo => {
return todo.id === payload.id
});
todo.done = payload.status;
}
}
}
ที่ Components/TodoList.vue
<template>
<todo-item
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@click="toggleStatus(todo.id)"
/>
</template>
<script>
...
export default {
...
computed: {
todos() {
return this.$store.state.todos;
}
},
methods: {
toggleStatus(id) {
this.$store.dispatch('toggleStatus', id);
}
}
}
</script>
ลองนึกภาพ TodoList ที่มันต้องมีทั้ง create, update, delete เพิ่มมาอีกสิครับยาวอยู่นะ
ถ้าพึ่งบารมี Vuex-ORM ล่ะจะเป็นอย่างไร #
ขั้นแรกเราก็สร้าง Model กันก่อนครับ กำหนดไปก่อนเลยว่ามี field อะไรบ้างแล้วจะให้มันอยู่ใน entity ไหน
store/models/Todo.js
import { Model } from '@vuex-orm/core';
export default class Todo extends Model {
static entity = 'todos';
static fields() {
return {
id: this.string(''),
title: this.string(''),
done: this.boolean(false),
};
}
}
store/index.js ก็มา register ตัว Model ที่เราสร้างไว้เมื่อสักครู่กับ database ของ Vuex-ORM
import Vue from 'vue';
import Vuex from 'vuex';
import VuexORM from '@vuex-orm/core';
import Todo from './models/Todo';
Vue.use(Vuex);
const database = new VuexORM.Database();
database.register(Todo);
const store = new Vuex.Store({
plugins: [VuexORM.install(database)],
});
export default store;
ส่วนของ component code จะน่ารักขึ้นเยอะเลย
<template>
<div>
<todo-item
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@clicked="toggleStatus"
/>
</div>
</template>
<script>
import TodoItem from '../components/TodoItem.vue';
import Todo from '../store/models/Todo';
export default {
...
computed: {
todos() {
return Todo.all();
},
},
methods: {
toggleStatus(id) {
const todo = Todo.find(id);
Todo.update({
where: id,
data: { done: !todo.done },
});
},
},
};
</script>
สังเกตไหมครับว่า code มันดูเป็นผู้เป็นคนมากขึ้น เราสามารถเรียก Todo ได้แบบนี้เลย
//แบบเดิม
this.$store.dispatch('toggleStatus', id);
//แบบ vuex-orm
const todo = Todo.find(id);
Todo.update({
where: id,
data: { done: !todo.done },
});
มันเหมือนจะยาวขึ้นนะ แต่ผมว่ามันเข้าใจง่ายกว่ามาก แถมนอกจาก update แล้วยังมี create, insert, delete ให้ด้วยนะครับ หรือแม้แต่จะ query แบบนี้
//หา todo ที่ยังไม่ done มาทั้งหมด
const todos = Todo.query().where('done', false).get();
ก็ทำได้โดยที่เราไม่ต้องไปเขียน function query เลยครับ Vuex-ORM เขามี Query Builder มาให้ในตัวแล้วสะดวกมากๆ
มี plugin ด้วยนะ #
นอกเหนือไปจากความสบายที่บอกไปแล้ว ยังมี plugin อีกนะ (plugin ของ plugin) แน่นอนว่าปัจจุบัน app เราก็ต้องทำงานกับ API อยู่แล้ว ตัวที่น่าจะได้ใช้กันก็มี
- Vuex ORM Axios - สำหรับใครที่ทำงานกับ RESTful API
- Vuex ORM GraphQL - สำหรับใครที่ใช้ GraphQL ก็มีด้วย แล้วตัวนี้เจ๋งขนาดที่มันเขียน query ให้เราได้เองเลยแหละ
สำหรับใครที่อยากลองไปศึกษาเพิ่มเติมก็สามารถเข้าไปดูได้ที่ Github repo ของผู้พัฒนาได้เลยครับ มีให้อ่านครบทุกอย่าง งงตรงไหนไปเปิดหาใน issue ใน repo ก่อน ถ้าไม่เจอก็หาใน StackOverflow ต่ออีกที แต่ถ้ายังงงจริงๆ ก็ inbox มาถามผมได้ที่ Facebook Page นะครับ (ถ้าผมตอบได้นะ 5555)