DEV Community

Cover image for Using Pinia ORM in Vue 3, Vuetify 3, Typescript
anhln
anhln

Posted on

Using Pinia ORM in Vue 3, Vuetify 3, Typescript

INTRODUCTION
Let's build an Todos application using Vue 3 with Vuetify 3, PiniaORM, TypeScript.

I will only be covering the basic implementation of the Vuex ORM example.

Pre-Requisites
This article assumes that the basic knowledge and understanding of familiarity with:

  • Vue 3(Composition API)
  • TypeScript
  • Vuetify 3
  • State Management in Vue

Project Structure
Image description

Vuetify 3 Setup

Pinia ORM Setup

  • Creating Database models Pinia: User.ts
import { Model } from "pinia-orm";
import Todo from "./Todo";

export class User extends Model {
  static entity = "users";

  static fields() {
    return {
      id: this.uid(),
      name: this.attr(""),
      todos: this.hasMany(Todo, "user_id"),
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

Todo.ts

import { Model } from "pinia-orm";
import { User } from "./User";

export default class Todo extends Model {
  static entity = "todos";

  static fields() {
    return {
      id: this.uid(),
      user_id: this.uid(),
      title: this.string(""),
      done: this.boolean(false),
      assignee: this.belongsTo(User, "user_id"),
    };
  }
}


Enter fullscreen mode Exit fullscreen mode

Creating stores in Pinia
In store/modules directory, add user and todo store

import { defineStore } from "pinia";
import { User } from "@/models/User";
import { useRepo } from "pinia-orm";
import data from "@/data";

const userRepo = useRepo(User);

export const useUserStore = defineStore("user", {
  state: () => ({
    users: [],
  }),
  actions: {
    initilizeUsers() {
      userRepo.save(data.users);
    },
    createNewUser(user: User) {
      if (!user) return;
      userRepo.save(user);
    },
  },
});

Enter fullscreen mode Exit fullscreen mode

Need to import the initialized data

// Emulating todo records which should be returned from API backend
// in the real world.
export default {ssssssssssssssssssssssssssssssssssssssssssssssss
  users: [
    {
      name: "John Doe",
      todos: [
        {
          title: "Create awesome application!",
          done: false,
        },
        {
          title: "Read the documentation",
          done: false,
        },
      ],
    },
    {
      name: "Johnny Doe",
      todos: [
        {
          title: "Star Vuex ORM repository",
          done: false,
        },
      ],
    },
  ],
};

Enter fullscreen mode Exit fullscreen mode

Todo store

import { defineStore } from "pinia";
import Todo from "@/models/Todo";
import { useRepo } from "pinia-orm";

const todoRepo = useRepo(Todo);
export const useTodoStore = defineStore("todo", {
  state: () => ({
    rawTodos: [],
  }),
  getters: {
    todos: () => {
      const todos = todoRepo.all();
      return todos;
    },
  },
  actions: {
    createNewTodo(todo: Todo) {
      if (!todo) return;
      todoRepo.save(todo);
    },
    save(todo: Todo) {
      todoRepo.save(todo);
    },
    update(todo: Todo, title: string) {
      todoRepo.save({ id: todo.id, title: title });
    },
    destroy(id: string) {
      todoRepo.destroy(id);
    },
  },
});

Enter fullscreen mode Exit fullscreen mode
  • In router, need to initilise data for users
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import { useUserStore } from "@/store/modules/user";

const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    name: "Home",
    component: () => import("@/views/Home.vue"),
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

router.beforeEach(() => {
  const store = useUserStore();
  if (!store.users.length) {
    store.initilizeUsers();
  }
});

export default router;

Enter fullscreen mode Exit fullscreen mode

Demo
This is source code:

Top comments (0)