
Create Adaptable Composable
Skill指导 agent 编写库级别的 Vue 组合式函数,让参数既能传普通值,也能传 ref 或 getter:按只读或可写选用 MaybeRefOrGetter 或 MaybeRef,并在 watch 等响应式副作用里用 toValue()、toRef() 统一取值。需要 Vue 3 或 Nuxt 3 以上。
name: create-adaptable-composable
description: Create a library-grade Vue composable that accepts maybe-reactive inputs (MaybeRef / MaybeRefOrGetter) so callers can pass a plain value, ref, or getter. Normalize inputs with toValue()/toRef() inside reactive effects (watch/watchEffect) to keep behavior predictable and reactive. Use this skill when user asks for creating adaptable or reusable composables.
license: MIT
metadata:
author: github.com/vuejs-ai
version: "17.0.0"
compatibility: Requires Vue 3 (or above) or Nuxt 3 (or above) project
Create Adaptable Composable
Adaptable composables are reusable functions that can accept both reactive and non-reactive inputs. This allows developers to use the composable in a variety of contexts without worrying about the reactivity of the inputs.
Steps to design an adaptable composable in Vue.js:
- Confirm the composable's purpose and API design and expected inputs/outputs.
- Identify inputs params that should be reactive (MaybeRef / MaybeRefOrGetter).
- Use
toValue()ortoRef()to normalize inputs inside reactive effects. - Implement the core logic of the composable using Vue's reactivity APIs.
Core Type Concepts
Type Utilities
/**
* value or writable ref (value/ref/shallowRef/writable computed)
*/
export type MaybeRef<T = any> = T | Ref<T> | ShallowRef<T> | WritableComputedRef<T>;
/**
* MaybeRef<T> + ComputedRef<T> + () => T
*/
export type MaybeRefOrGetter<T = any> = MaybeRef<T> | ComputedRef<T> | (() => T);
Policy and Rules
- Read-only, computed-friendly input: use
MaybeRefOrGetter - Needs to be writable / two-way input: use
MaybeRef - Parameter might be a function value (callback/predicate/comparator): do not use
MaybeRefOrGetter, or you may accidentally invoke it as a getter. - DOM/Element targets: if you want computed/derived targets, use
MaybeRefOrGetter.
When MaybeRefOrGetter or MaybeRef is used:
- resolve reactive value using
toRef()(e.g. watcher source) - resolve non-reactive value using
toValue()
Examples
Adaptable useDocumentTitle Composable: read-only title parameter
import { watch, toRef } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
export function useDocumentTitle(title: MaybeRefOrGetter<string>) {
watch(toRef(title), (t) => {
document.title = t
}, { immediate: true })
}
Adaptable useCounter Composable: two-way writable count parameter
import { watch, toRef } from 'vue'
import type { MaybeRef } from 'vue'
function useCounter(count: MaybeRef<number>) {
const countRef = toRef(count)
function add() {
countRef.value++
}
return { add }
}
相關資源

Vue Best Practices
SkillVue 开发的默认工作流:以 Vue 3、Composition API 和 script setup 加 TypeScript 为标准,编码前先读响应式、单文件组件、数据流与组合式函数等核心参考并规划组件拆分,插槽、过渡动画、性能优化等专题按需加载,最后逐项自检。
vuejs-ai/skills2.9k
Antfu Conventions
SkillAnthony Fu 对 JavaScript / TypeScript 项目的约定与工具偏好:代码组织、显式导入、Vitest 测试写法,以及 @antfu/ni、开启 antislop 的 @antfu/eslint-config、Knip、tsdown 和统一的 ci 脚本,新建项目时参照 antfu/starter-ts 模板。
antfu/skills6k
Nuxt
SkillNuxt 5 全栈 Vue 框架的参考:目录结构、配置、文件路由、useFetch 等数据获取、自动导入、服务端路由、渲染模式、SSR 与水合注意事项、模块与 Layers,重点说明 Nuxt 5 改用 Nitro v3 与 Vite 8 带来的变化。由 Anthony Fu 从官方文档生成。
antfu/skills6k
Pinia
SkillPinia v4 状态管理的参考:定义 store 的 state、getters 与 actions,插件、在 store 中使用组合式函数、store 之间的组合,测试、SSR、Nuxt 集成与 HMR;建议优先用 Setup Store、解构时用 storeToRefs。由 Anthony Fu 从官方文档生成。
antfu/skills6k
Vue
SkillVue 3.5 的参考:<script setup> 与 defineProps、defineEmits、defineModel 等宏,响应式 API、侦听器与生命周期,Transition、Teleport、Suspense、KeepAlive 等内置组件。要求 agent 一律用组合式 API 与 TypeScript 的 <script setup>,不需要深层响应时优先 shallowRef。由 Anthony Fu 从官方文档生成。
antfu/skills6k
Vue Options API Best Practices
Skill面向使用 Options API(data()、methods、this)的 Vue 3 项目:说明如何借助 defineComponent 获得 TypeScript 类型推断,为 props、事件处理器和 computed 加类型,以及 methods 与生命周期钩子里不要用箭头函数、防抖函数不要在实例间共享状态等常见坑。
vuejs-ai/skills2.9k