<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: anhln</title>
    <description>The latest articles on DEV Community by anhln (@anhln).</description>
    <link>https://dev.to/anhln</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F848081%2F83a384c5-a84c-4251-84f7-47c2a4cf3c6e.jpeg</url>
      <title>DEV Community: anhln</title>
      <link>https://dev.to/anhln</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anhln"/>
    <language>en</language>
    <item>
      <title>Using Pinia ORM in Vue 3, Vuetify 3, Typescript</title>
      <dc:creator>anhln</dc:creator>
      <pubDate>Tue, 11 Apr 2023 03:37:02 +0000</pubDate>
      <link>https://dev.to/anhln/how-to-use-pinia-orm-in-vue-3-vuetify-3-typescript-1ha2</link>
      <guid>https://dev.to/anhln/how-to-use-pinia-orm-in-vue-3-vuetify-3-typescript-1ha2</guid>
      <description>&lt;p&gt;&lt;strong&gt;INTRODUCTION&lt;/strong&gt;&lt;br&gt;
Let's build an Todos application using Vue 3 with Vuetify 3, PiniaORM, TypeScript.&lt;/p&gt;

&lt;p&gt;I will only be covering the basic implementation of the Vuex ORM example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-Requisites&lt;/strong&gt;&lt;br&gt;
This article assumes that the basic knowledge and understanding of familiarity with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue 3(Composition API)&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Vuetify 3&lt;/li&gt;
&lt;li&gt;State Management in Vue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Project Structure&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1bjua3j3x8mg4n8tm4v8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1bjua3j3x8mg4n8tm4v8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vuetify 3 Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pinia ORM Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating Database models Pinia: &lt;em&gt;User.ts&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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"),
    };
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Todo.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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"),
    };
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating stores in Pinia&lt;br&gt;
In store/modules directory, add user and todo store&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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: () =&amp;gt; ({
    users: [],
  }),
  actions: {
    initilizeUsers() {
      userRepo.save(data.users);
    },
    createNewUser(user: User) {
      if (!user) return;
      userRepo.save(user);
    },
  },
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to import the initialized data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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,
        },
      ],
    },
  ],
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todo store&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineStore } from "pinia";
import Todo from "@/models/Todo";
import { useRepo } from "pinia-orm";

const todoRepo = useRepo(Todo);
export const useTodoStore = defineStore("todo", {
  state: () =&amp;gt; ({
    rawTodos: [],
  }),
  getters: {
    todos: () =&amp;gt; {
      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);
    },
  },
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In router, need to initilise data for users
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import { useUserStore } from "@/store/modules/user";

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

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

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

export default router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;br&gt;
This is source code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/anhln/vue3-vite-ts-pinia-orm-todo" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>piniaorm</category>
      <category>store</category>
    </item>
  </channel>
</rss>
