Skip to content

Vue

Terminal window
bun add @slop-ai/client @slop-ai/vue

Create a SLOP client instance for your app:

import { createSlop } from "@slop-ai/client";
export const slop = createSlop({
id: "notes-app",
name: "Notes App",
});

The useSlop composable registers a node on mount, updates it reactively, and unregisters it on unmount.

import { action, useSlop } from "@slop-ai/vue";

The signature is useSlop(client, pathOrGetter, descriptorFactory) where the descriptor is wrapped in a function so Vue can track reactive dependencies.

<script setup lang="ts">
import { ref } from "vue";
import { action, useSlop } from "@slop-ai/vue";
import { slop } from "./slop";
interface Note {
id: string;
title: string;
pinned: boolean;
}
const notes = ref<Note[]>([]);
useSlop(slop, "/notes", () => ({
type: "collection",
props: { count: notes.value.length },
actions: {
create: action({ title: "string" }, ({ title }) => {
notes.value.push({
id: crypto.randomUUID(),
title,
pinned: false,
});
}),
clear_all: action(() => {
notes.value = [];
}, { dangerous: true }),
},
items: notes.value.map((note) => ({
id: note.id,
props: { title: note.title, pinned: note.pinned },
actions: {
toggle_pin: action(() => {
notes.value = notes.value.map((entry) =>
entry.id === note.id ? { ...entry, pinned: !entry.pinned } : entry,
);
}),
},
})),
}));
</script>
<template>
<ul>
<li v-for="note in notes" :key="note.id">
{{ note.pinned ? "📌 " : "" }}{{ note.title }}
</li>
</ul>
</template>