Vuetify & vue-postgrest todos

From UVOO Tech Wiki
Revision as of 10:27, 10 August 2025 by Busk (talk | contribs) (Created page with "Perfect—here’s a Vue + Vuetify + vue-postgrest CRUD example for a todos table. It shows list, add, edit, and delete using v-data-table and dialogs. It uses vue-postgrest...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Perfect—here’s a Vue + Vuetify + vue-postgrest CRUD example for a todos table. It shows list, add, edit, and delete using v-data-table and dialogs. It uses vue-postgrest’s pg mixin, pg.$new() for creates, and per-row item.$patch() / item.$delete() for updates/deletes (that’s how the library is designed).


Project setup

Vue 3 + Vite + Vuetify

npm create vite@latest vue-pg-todos -- --template vue cd vue-pg-todos npm i vuetify @mdi/font vue-postgrest

main.ts

// src/main.ts import { createApp } from 'vue' import App from './App.vue'

// Vuetify import 'vuetify/styles' import { createVuetify } from 'vuetify' import { aliases, mdi } from 'vuetify/iconsets/mdi' import '@mdi/font/css/materialdesignicons.css' const vuetify = createVuetify({

 icons: { defaultSet: 'mdi', aliases, sets: { mdi } },

})

// vue-postgrest import VuePostgrest from 'vue-postgrest'

// Create app const app = createApp(App)

// Point to your PostgREST base URL app.use(VuePostgrest, {

 apiRoot: 'http://localhost:3000/',   // e.g. http://localhost:3000/
 // headers: { Authorization: Bearer ${yourJWT} }  // if you use JWT

})

app.use(vuetify).mount('#app')

App.vue


CRUD component


PostgREST side (example table)

-- example schema CREATE TABLE public.todos(

 id serial PRIMARY KEY,
 title text NOT NULL,
 done boolean NOT NULL DEFAULT false,
 created_at timestamptz NOT NULL DEFAULT now()

);

GRANT SELECT, INSERT, UPDATE, DELETE ON public.todos TO anon; -- or your web role


Why this works

vue-postgrest exposes a pg mixin that fetches a route (table/view) and returns a GenericCollection of GenericModels in this.pg. You can mutate model fields with v-model and persist via model.$patch(); create via pg.$new(...).$post(); delete via model.$delete().

query.order / query.select and other keys map directly to PostgREST query syntax (ordering, filtering).

count: 'exact' enables total counts via Content-Range, useful if you later add server-side pagination UI.

If you want server-side pagination with v-data-table (using headers for sort → passing to pgConfig.query.order, and using limit/offset with pg.$range.totalCount), I can wire that up too.