DEV Community

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

Posted on

3

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:

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up