Using Pinia ORM in Vue 3, Vuetify 3, Typescript
Tags: vue, typescript, piniaorm, store
Published: 2023-04-11 03:37:02

**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bjua3j3x8mg4n8tm4v8.png)

**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"),
    };
  }
}
```
_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"),
    };
  }
}


```
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);
    },
  },
});

```
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,
        },
      ],
    },
  ],
};

```
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);
    },
  },
});

```
- 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;

```
**Demo**
This is source code:
- [Github Repo](https://github.com/anhln/vue3-vite-ts-pinia-orm-todo)