[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FJSYJZZRDWN1J35Q92APZG":3,"skill-same:01M6FJSYJZZRDWN1J35Q92APZG":48},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":21,"linkOnly":22,"markdownContent":23,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":30,"ownerHtmlUrl":31,"ownerBlogUrl":6,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M6FJSYJZZRDWN1J35Q92APZG","create-adaptable-composable",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fvuejs-ai\u002Fskills\u002Fcreate-adaptable-composable\u002FSKILL.md",[],[18,19,20],"composable","create","create adaptable composable","2026-11-10 10:12:30",false,"# Create Adaptable Composable\n\nAdaptable 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.\n\nSteps to design an adaptable composable in Vue.js:\n1. Confirm the composable's purpose and API design and expected inputs\u002Foutputs.\n2. Identify inputs params that should be reactive (MaybeRef \u002F MaybeRefOrGetter).\n3. Use `toValue()` or `toRef()` to normalize inputs inside reactive effects.\n4. Implement the core logic of the composable using Vue's reactivity APIs.\n\n## Core Type Concepts\n\n### Type Utilities\n\n```ts\n\u002F**\n * value or writable ref (value\u002Fref\u002FshallowRef\u002Fwritable computed)\n *\u002F\nexport type MaybeRef\u003CT = any> = T | Ref\u003CT> | ShallowRef\u003CT> | WritableComputedRef\u003CT>;\n\n\u002F**\n * MaybeRef\u003CT> + ComputedRef\u003CT> + () => T\n *\u002F\nexport type MaybeRefOrGetter\u003CT = any> = MaybeRef\u003CT> | ComputedRef\u003CT> | (() => T);\n```\n\n### Policy and Rules\n\n- Read-only, computed-friendly input: use `MaybeRefOrGetter`\n- Needs to be writable \u002F two-way input: use `MaybeRef`\n- Parameter might be a function value (callback\u002Fpredicate\u002Fcomparator): do not use `MaybeRefOrGetter`, or you may accidentally invoke it as a getter.\n- DOM\u002FElement targets: if you want computed\u002Fderived targets, use `MaybeRefOrGetter`.\n\nWhen `MaybeRefOrGetter` or `MaybeRef` is used: \n- resolve reactive value using `toRef()` (e.g. watcher source)\n- resolve non-reactive value using `toValue()`\n\n### Examples\n\nAdaptable `useDocumentTitle` Composable: read-only title parameter\n\n```ts\nimport { watch, toRef } from 'vue'\nimport type { MaybeRefOrGetter } from 'vue'\n\nexport function useDocumentTitle(title: MaybeRefOrGetter\u003Cstring>) {\n  watch(toRef(title), (t) => {\n    document.title = t\n  }, { immediate: true })\n}\n```\n\nAdaptable `useCounter` Composable: two-way writable count parameter\n\n```ts\nimport { watch, toRef } from 'vue'\nimport type { MaybeRef } from 'vue'\n\nfunction useCounter(count: MaybeRef\u003Cnumber>) {\n  const countRef = toRef(count)\n  function add() {\n    countRef.value++\n  }\n  return { add }\n}\n```\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fvuejs-ai\u002Fskills\u002Fcreate-adaptable-composable",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill create-adaptable-composable",{"tool":40,"command":41},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill create-adaptable-composable",{"tool":43,"command":44},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill create-adaptable-composable","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fvuejs-ai\u002Fskills\u002Fcreate-adaptable-composable\u002FSKILL.md",true,[],[49,63,73,82,88,95],{"skillNo":50,"name":51,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":52,"categories":53,"keywords":59,"publishedAt":21},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[54],{"categoryNo":55,"categoryName":56,"taxonomyType":57,"taxonomyTypeDesc":58},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[60,61,62],"model","model hierarchy","model hierarchy skill",{"skillNo":64,"name":65,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":69,"publishedAt":21},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[68],{"categoryNo":55,"categoryName":56,"taxonomyType":57,"taxonomyTypeDesc":58},[70,71,72],"MCP","zoom","zoom mcp",{"skillNo":74,"name":75,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":21},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[79,80,81,71],"sdk","zoom apps sdk","apps",{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":21},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[84],{"skillNo":89,"name":90,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":94,"publishedAt":21},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[93],{"categoryNo":55,"categoryName":56,"taxonomyType":57,"taxonomyTypeDesc":58},[90],{"skillNo":96,"name":97,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":21},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[97]]