npx claudepluginhub vueuse/skillsA skill for using VueUse composables in Vue.js / Nuxt projects with references for 260+ functions.
Share bugs, ideas, or general feedback.
Agent Skills for VueUse — a collection of essential Vue Composition Utilities.
[!IMPORTANT] Experimental Project: Aims to help AI agents use libraries more accurately with fewer tokens. Feedback is welcome.
AGENTS.mdnpx skills add vueuse/skills
An alternative for Claude Code users:
# Add marketplace
/plugin marketplace add vueuse/skills
# Install individual skills
/plugin install vueuse-functions@vueuse-skills
Install VueUse in your Vue or Nuxt project, then instruct the agent. It will automatically leverage VueUse to assist development.
Example prompt:
create a todo app with the following features:
- save todos to local storage
- show remains todo count on browser title
- add a copy button for each todo items
- infinite scrolling for this todo list
- dark / light mode
<script setup lang="ts">
import { computed, ref } from 'vue'
import {
useClipboard,
useColorMode,
useInfiniteScroll,
useLocalStorage,
useTitle,
} from '@vueuse/core'
type Todo = {
id: number
text: string
done: boolean
}
const seedTexts = [
'Review project goals',
'Plan the next sprint',
'Reply to client email',
]
const defaultTodos = Array.from({ length: 36 }, (_, index) => ({
id: index + 1,
text:
seedTexts[index % seedTexts.length] +
(index >= seedTexts.length ? ` #${index + 1}` : ''),
done: index % 7 === 0,
}))
const todos = useLocalStorage<Todo[]>('focus-flow-todos', defaultTodos)
const nextId = ref(
todos.value.reduce((max, todo) => Math.max(max, todo.id), 0) + 1,
)
const newTodo = ref('')
const totalCount = computed(() => todos.value.length)
const remainingCount = computed(() =>
todos.value.filter((todo) => !todo.done).length,
)
const completedCount = computed(
() => totalCount.value - remainingCount.value,
)
useTitle(computed(() => `Todos (${remainingCount.value})`))
const mode = useColorMode({
attribute: 'data-theme',
disableTransition: false,
})
const isDark = computed(() => mode.value === 'dark')
const toggleMode = () => {
mode.value = isDark.value ? 'light' : 'dark'
}
const { copy, copied, isSupported } = useClipboard()
const lastCopiedId = ref<number | null>(null)
const handleCopy = async (todo: Todo) => {
await copy(todo.text)
lastCopiedId.value = todo.id
}
const pageSize = 8
const visibleCount = ref(Math.min(pageSize, todos.value.length))
const visibleTodos = computed(() => todos.value.slice(0, visibleCount.value))
const listRef = ref<HTMLElement | null>(null)
const { isLoading } = useInfiniteScroll(
listRef,
() => {
if (visibleCount.value < todos.value.length) {
visibleCount.value = Math.min(
visibleCount.value + pageSize,
todos.value.length,
)
}
},
{
distance: 120,
canLoadMore: () => visibleCount.value < todos.value.length,
},
)
const syncVisibleCount = () => {
if (todos.value.length <= pageSize) {
visibleCount.value = todos.value.length
return
}
if (visibleCount.value === 0) {
visibleCount.value = pageSize
return
}
if (visibleCount.value > todos.value.length) {
visibleCount.value = todos.value.length
}
}
const addTodo = () => {
const value = newTodo.value.trim()
if (!value)
return
todos.value.unshift({
id: nextId.value++,
text: value,
done: false,
})
newTodo.value = ''
syncVisibleCount()
}
const removeTodo = (id: number) => {
todos.value = todos.value.filter((todo) => todo.id !== id)
syncVisibleCount()
}
</script>
<template>
<div class="page">
<div class="shell">
<header class="header">
<div>
<p class="eyebrow">Minimal todo tracker</p>
<h1>Focus Flow</h1>
<p class="subtitle">
Keep a lightweight list, copy tasks with a click, and scroll as the
list grows.
</p>
</div>
<button class="btn ghost mode-toggle" type="button" @click="toggleMode">
<span class="mode-dot" :class="{ dark: isDark }" />
<span>{{ isDark ? 'Dark' : 'Light' }} mode</span>
</button>
</header>