[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EEB2EN79HTZH0MB0179Z81":3,"skill-same:01M6EEB2EN79HTZH0MB0179Z81":51},{"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":18,"linkOnly":19,"markdownContent":20,"markdownBody":20,"frontMatter":21,"refName":22,"commitSha":23,"skillDirectory":24,"forksCount":25,"repositoryHtmlUrl":26,"repositoryHomepageUrl":27,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M6EEB2EN79HTZH0MB0179Z81","alpine",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\u002FTerminalSkills\u002Fskills\u002Falpine\u002FSKILL.md",[],[5],"2026-11-10 10:12:30",false,"# Alpine.js\n\nAlpine.js adds reactive behavior directly in HTML markup using `x-` attributes. It's ideal for adding interactivity to server-rendered pages without a build step or SPA framework.\n\n## Installation\n\n```html\n\u003C!-- index.html — add Alpine via CDN -->\n\u003Cscript defer src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Falpinejs@3.x.x\u002Fdist\u002Fcdn.min.js\">\u003C\u002Fscript>\n\u003C!-- Or: npm install alpinejs -->\n```\n\n```javascript\n\u002F\u002F main.js — npm module setup\nimport Alpine from 'alpinejs';\nwindow.Alpine = Alpine;\nAlpine.start();\n```\n\n## Core Directives\n\n```html\n\u003C!-- templates\u002Fbasics.html — fundamental Alpine directives -->\n\u003Cdiv x-data=\"{ open: false, count: 0 }\">\n  \u003C!-- Toggle visibility -->\n  \u003Cbutton @click=\"open = !open\">Toggle\u003C\u002Fbutton>\n  \u003Cdiv x-show=\"open\" x-transition>\n    \u003Cp>This content can be toggled\u003C\u002Fp>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Reactive counter -->\n  \u003Cp>Count: \u003Cspan x-text=\"count\">\u003C\u002Fspan>\u003C\u002Fp>\n  \u003Cbutton @click=\"count++\">Increment\u003C\u002Fbutton>\n\n  \u003C!-- Conditional rendering (removes from DOM) -->\n  \u003Ctemplate x-if=\"count > 5\">\n    \u003Cp>Count is greater than 5!\u003C\u002Fp>\n  \u003C\u002Ftemplate>\n\u003C\u002Fdiv>\n```\n\n## Data Binding\n\n```html\n\u003C!-- templates\u002Fbinding.html — two-way binding and attribute binding -->\n\u003Cdiv x-data=\"{ name: '', color: 'blue' }\">\n  \u003C!-- Two-way binding -->\n  \u003Cinput x-model=\"name\" placeholder=\"Your name\" \u002F>\n  \u003Cp>Hello, \u003Cspan x-text=\"name || 'stranger'\">\u003C\u002Fspan>!\u003C\u002Fp>\n\n  \u003C!-- Attribute binding -->\n  \u003Cdiv :class=\"{ 'text-red': color === 'red', 'text-blue': color === 'blue' }\">\n    Colored text\n  \u003C\u002Fdiv>\n  \u003Cselect x-model=\"color\">\n    \u003Coption value=\"blue\">Blue\u003C\u002Foption>\n    \u003Coption value=\"red\">Red\u003C\u002Foption>\n  \u003C\u002Fselect>\n\n  \u003C!-- Style binding -->\n  \u003Cdiv :style=\"{ color: color, fontWeight: name ? 'bold' : 'normal' }\">\n    Dynamic styles\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n## Loops\n\n```html\n\u003C!-- templates\u002Floops.html — iterating over data -->\n\u003Cdiv x-data=\"{ items: ['Apples', 'Bananas', 'Cherries'], newItem: '' }\">\n  \u003Cul>\n    \u003Ctemplate x-for=\"(item, index) in items\" :key=\"index\">\n      \u003Cli>\n        \u003Cspan x-text=\"item\">\u003C\u002Fspan>\n        \u003Cbutton @click=\"items.splice(index, 1)\">×\u003C\u002Fbutton>\n      \u003C\u002Fli>\n    \u003C\u002Ftemplate>\n  \u003C\u002Ful>\n\n  \u003Cform @submit.prevent=\"items.push(newItem); newItem = ''\">\n    \u003Cinput x-model=\"newItem\" placeholder=\"Add item\" \u002F>\n    \u003Cbutton type=\"submit\">Add\u003C\u002Fbutton>\n  \u003C\u002Fform>\n\u003C\u002Fdiv>\n```\n\n## Event Handling\n\n```html\n\u003C!-- templates\u002Fevents.html — event modifiers and custom events -->\n\u003Cdiv x-data=\"{ count: 0 }\">\n  \u003C!-- Modifiers -->\n  \u003Cbutton @click.prevent=\"count++\">Prevent default\u003C\u002Fbutton>\n  \u003Cbutton @click.once=\"alert('Only once!')\">Click once\u003C\u002Fbutton>\n  \u003Cinput @keydown.enter=\"submitForm()\" @keydown.escape=\"cancel()\" \u002F>\n\n  \u003C!-- Debounce -->\n  \u003Cinput @input.debounce.300ms=\"search($event.target.value)\" placeholder=\"Search...\" \u002F>\n\n  \u003C!-- Listen to events from window -->\n  \u003Cdiv @custom-event.window=\"count++\">\n    Count: \u003Cspan x-text=\"count\">\u003C\u002Fspan>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Dispatch custom event -->\n  \u003Cbutton @click=\"$dispatch('custom-event')\">Dispatch\u003C\u002Fbutton>\n\u003C\u002Fdiv>\n```\n\n## Component Patterns\n\n```html\n\u003C!-- templates\u002Fdropdown.html — dropdown component -->\n\u003Cdiv x-data=\"{ open: false }\" @click.outside=\"open = false\">\n  \u003Cbutton @click=\"open = !open\">\n    Menu\n    \u003Cspan :class=\"{ 'rotate-180': open }\" x-text=\"open ? '▲' : '▼'\">\u003C\u002Fspan>\n  \u003C\u002Fbutton>\n\n  \u003Cdiv x-show=\"open\" x-transition.origin.top.left\n    @keydown.escape.window=\"open = false\"\n    class=\"dropdown-menu\">\n    \u003Ca href=\"\u002Fprofile\">Profile\u003C\u002Fa>\n    \u003Ca href=\"\u002Fsettings\">Settings\u003C\u002Fa>\n    \u003Cbutton @click=\"$dispatch('logout')\">Logout\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n```html\n\u003C!-- templates\u002Ftabs.html — tabs component -->\n\u003Cdiv x-data=\"{ activeTab: 'general' }\">\n  \u003Cnav>\n    \u003Cbutton @click=\"activeTab = 'general'\" :class=\"{ active: activeTab === 'general' }\">General\u003C\u002Fbutton>\n    \u003Cbutton @click=\"activeTab = 'security'\" :class=\"{ active: activeTab === 'security' }\">Security\u003C\u002Fbutton>\n  \u003C\u002Fnav>\n\n  \u003Cdiv x-show=\"activeTab === 'general'\">General settings...\u003C\u002Fdiv>\n  \u003Cdiv x-show=\"activeTab === 'security'\">Security settings...\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n## Reusable Data with Alpine.data\n\n```html\n\u003C!-- templates\u002Freusable.html — extracting reusable components -->\n\u003Cscript>\n  \u002F\u002F Register reusable component\n  document.addEventListener('alpine:init', () => {\n    Alpine.data('todoList', () => ({\n      items: [],\n      newItem: '',\n      add() {\n        if (this.newItem.trim()) {\n          this.items.push({ text: this.newItem, done: false });\n          this.newItem = '';\n        }\n      },\n      remove(index) {\n        this.items.splice(index, 1);\n      },\n      get remaining() {\n        return this.items.filter(i => !i.done).length;\n      },\n    }));\n  });\n\u003C\u002Fscript>\n\n\u003C!-- Use anywhere -->\n\u003Cdiv x-data=\"todoList\">\n  \u003Cform @submit.prevent=\"add\">\n    \u003Cinput x-model=\"newItem\" placeholder=\"New todo\" \u002F>\n    \u003Cbutton type=\"submit\">Add\u003C\u002Fbutton>\n  \u003C\u002Fform>\n  \u003Cp x-text=\"`${remaining} remaining`\">\u003C\u002Fp>\n  \u003Ctemplate x-for=\"(item, i) in items\" :key=\"i\">\n    \u003Cdiv>\n      \u003Cinput type=\"checkbox\" x-model=\"item.done\" \u002F>\n      \u003Cspan x-text=\"item.text\" :class=\"{ 'line-through': item.done }\">\u003C\u002Fspan>\n      \u003Cbutton @click=\"remove(i)\">×\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  \u003C\u002Ftemplate>\n\u003C\u002Fdiv>\n```\n\n## Working with htmx\n\n```html\n\u003C!-- templates\u002Falpine-htmx.html — Alpine + htmx together -->\n\u003Cdiv x-data=\"{ editing: false }\" id=\"article-42\">\n  \u003Cdiv x-show=\"!editing\">\n    \u003Ch2>Article Title\u003C\u002Fh2>\n    \u003Cbutton @click=\"editing = true\">Edit\u003C\u002Fbutton>\n    \u003Cbutton hx-delete=\"\u002Farticles\u002F42\" hx-target=\"#article-42\" hx-swap=\"outerHTML\">Delete\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cform x-show=\"editing\" hx-put=\"\u002Farticles\u002F42\" hx-target=\"#article-42\" hx-swap=\"outerHTML\">\n    \u003Cinput name=\"title\" value=\"Article Title\" \u002F>\n    \u003Cbutton type=\"submit\">Save\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\" @click=\"editing = false\">Cancel\u003C\u002Fbutton>\n  \u003C\u002Fform>\n\u003C\u002Fdiv>\n```\n\n## Stores (Global State)\n\n```html\n\u003C!-- templates\u002Fstores.html — Alpine stores for shared state -->\n\u003Cscript>\n  document.addEventListener('alpine:init', () => {\n    Alpine.store('notifications', {\n      items: [],\n      add(msg) { this.items.push({ text: msg, id: Date.now() }) },\n      remove(id) { this.items = this.items.filter(n => n.id !== id) },\n    });\n  });\n\u003C\u002Fscript>\n\n\u003Cdiv x-data @click=\"$store.notifications.add('Button clicked!')\">Click me\u003C\u002Fdiv>\n\n\u003Cdiv x-data>\n  \u003Ctemplate x-for=\"n in $store.notifications.items\" :key=\"n.id\">\n    \u003Cdiv class=\"toast\" x-text=\"n.text\" @click=\"$store.notifications.remove(n.id)\">\u003C\u002Fdiv>\n  \u003C\u002Ftemplate>\n\u003C\u002Fdiv>\n```\n\n## Magic Properties\n\n```html\n\u003C!-- templates\u002Fmagic.html — Alpine magic properties -->\n\u003Cdiv x-data=\"{ items: [] }\">\n  \u003C!-- $refs — reference DOM elements -->\n  \u003Cinput x-ref=\"input\" \u002F>\n  \u003Cbutton @click=\"$refs.input.focus()\">Focus input\u003C\u002Fbutton>\n\n  \u003C!-- $nextTick — run after DOM update -->\n  \u003Cbutton @click=\"items.push('new'); $nextTick(() => $refs.list.scrollTo(0, 99999))\">\n    Add & scroll\n  \u003C\u002Fbutton>\n  \u003Cdiv x-ref=\"list\" style=\"max-height:200px;overflow:auto\">\n    \u003Ctemplate x-for=\"item in items\">\u003Cp x-text=\"item\">\u003C\u002Fp>\u003C\u002Ftemplate>\n  \u003C\u002Fdiv>\n\n  \u003C!-- $watch — react to data changes -->\n  \u003Cdiv x-init=\"$watch('items', (val) => console.log('items changed:', val))\">\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n## Key Patterns\n\n- Use `x-data` on a parent element to define reactive scope — everything inside shares that state\n- Use `x-show` for toggling visibility (CSS), `x-if` for conditional DOM insertion\n- Use `x-model` for two-way binding on inputs, selects, checkboxes\n- Use event modifiers (`.prevent`, `.stop`, `.debounce`, `.outside`) to reduce boilerplate\n- Use `Alpine.data()` to extract reusable components with methods and computed properties\n- Use `Alpine.store()` for global state shared across components\n- Pairs excellently with htmx: Alpine handles UI state, htmx handles server communication\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Falpine",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":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill alpine",{"tool":37,"command":38},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill alpine",{"tool":40,"command":41},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill alpine","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Falpine\u002FSKILL.md",true,[45],{"path":46,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":49,"sourceHtmlUrl":50},"plan-document-reviewer-prompt.md","REFERENCE","参考文档",1713,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.openhands\u002Fskills\u002Fwriting-plans\u002Fplan-document-reviewer-prompt.md",[52,66,76,85,91,98],{"skillNo":53,"name":54,"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":55,"categories":56,"keywords":62,"publishedAt":18},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[57],{"categoryNo":58,"categoryName":59,"taxonomyType":60,"taxonomyTypeDesc":61},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[63,64,65],"model","model hierarchy","model hierarchy skill",{"skillNo":67,"name":68,"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":69,"categories":70,"keywords":72,"publishedAt":18},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[71],{"categoryNo":58,"categoryName":59,"taxonomyType":60,"taxonomyTypeDesc":61},[73,74,75],"MCP","zoom","zoom mcp",{"skillNo":77,"name":78,"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":79,"categories":80,"keywords":81,"publishedAt":18},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[82,83,84,74],"sdk","zoom apps sdk","apps",{"skillNo":86,"name":87,"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":88,"categories":89,"keywords":90,"publishedAt":18},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[87],{"skillNo":92,"name":93,"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":94,"categories":95,"keywords":97,"publishedAt":18},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[96],{"categoryNo":58,"categoryName":59,"taxonomyType":60,"taxonomyTypeDesc":61},[93],{"skillNo":99,"name":100,"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":101,"categories":102,"keywords":103,"publishedAt":18},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[100]]