{"id":13435107,"url":"https://github.com/pikax/vue-composable","last_synced_at":"2025-05-15T03:05:45.565Z","repository":{"id":35264707,"uuid":"216648976","full_name":"pikax/vue-composable","owner":"pikax","description":"Vue composition-api composable components. i18n, validation, pagination, fetch, etc. +50 different composables","archived":false,"fork":false,"pushed_at":"2023-02-03T05:13:30.000Z","size":20912,"stargazers_count":1182,"open_issues_count":24,"forks_count":64,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-04T16:02:12.432Z","etag":null,"topics":["breakpoint","composition-api","hooks","pagination","tailwindcss","typescript","utility-library","validation","vue","vue-next","vue3","vuejs"],"latest_commit_sha":null,"homepage":"https://pikax.me/vue-composable/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pikax.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"pikax"}},"created_at":"2019-10-21T19:28:35.000Z","updated_at":"2025-04-22T18:27:53.000Z","dependencies_parsed_at":"2023-02-18T03:45:57.082Z","dependency_job_id":null,"html_url":"https://github.com/pikax/vue-composable","commit_stats":null,"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikax%2Fvue-composable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikax%2Fvue-composable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikax%2Fvue-composable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikax%2Fvue-composable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pikax","download_url":"https://codeload.github.com/pikax/vue-composable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254264765,"owners_count":22041793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["breakpoint","composition-api","hooks","pagination","tailwindcss","typescript","utility-library","validation","vue","vue-next","vue3","vuejs"],"created_at":"2024-07-31T03:00:32.689Z","updated_at":"2025-05-15T03:05:45.545Z","avatar_url":"https://github.com/pikax.png","language":"TypeScript","funding_links":["https://github.com/sponsors/pikax"],"categories":["✨ Composition API functions","HarmonyOS","Packages","Components \u0026 Libraries","TypeScript","Thanks","Utilities [🔝](#readme)"],"sub_categories":["Windows Manager","Utilities","Vue 2"],"readme":"# vue-composable\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://pikax.me/vue-composable/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg width=\"250\" src=\"https://pikax.me/vue-composable/assets/logo.svg\" alt=\"vue-composable logo\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n[![CircleCI](https://circleci.com/gh/pikax/vue-composable.svg?style=svg)](https://circleci.com/gh/pikax/vue-composable)\n[![Coverage Status](https://coveralls.io/repos/github/pikax/vue-composable/badge.svg?branch=master)](https://coveralls.io/github/pikax/vue-composable?branch=master)\n[![npm version](https://badge.fury.io/js/vue-composable.svg)](https://badge.fury.io/js/vue-composable)\n[![bundle size](https://badgen.net/bundlephobia/minzip/vue-composable)](https://bundlephobia.com/result?p=vue-composable)\n\n\u003cp align=\"center\"\u003eOut-of-the-box ready to use composables\u003c/p\u003e\n\n- **🌴 TreeShakable**\n- **🧙‍♂️ Fully Typescript**\n- **💚 Vue 3 and 2 support**\n- **🔨 Vue Devtools support**\n\n## Introduction\n\nThis library aim is to be one stop shop for many real-world composable functions, with aggressive tree-shaking to keep it light on your end code.\n\n## Installing\n\n```bash\n# @vue/composition-api\n\n# install with yarn\nyarn add @vue/composition-api vue-composable\n\n# install with npm\nnpm install @vue/composition-api vue-composable\n\n# vue 3\n\n# install with yarn\nyarn add vue-composable\n\n# install with npm\nnpm install vue-composable\n```\n\n## Documentation\n\nCheck our [documentation](https://pikax.me/vue-composable/)\n\n### Composable\n\n### Event\n\n- [Event](https://pikax.me/vue-composable/composable/event/event) - Attach event listener to a DOM element\n- [Mouse Move](https://pikax.me/vue-composable/composable/event/onMouseMove) - Attach `mousemove` listener to a DOM element\n- [Resize](https://pikax.me/vue-composable/composable/event/onResize) - Attach `resize` listener to a DOM element\n- [Scroll](https://pikax.me/vue-composable/composable/event/onScroll) - Attach `scroll` listener to a DOM element\n- [onOutsidePress](https://pikax.me/vue-composable/composable/event/onOutsidePress) - Execute callback when click is outside of element\n\n### Dom\n\n- [Mouse distance from Element](https://pikax.me/vue-composable/composable/dom/mouseDistanceFromElement) - Distance in pixels from an element center\n\n### Date\n\n- [useNow](https://pikax.me/vue-composable/composable/date/now) : Return reactive custom timer with specified refresh rate\n- [useDateNow](https://pikax.me/vue-composable/composable/date/dateNow) : Returns reactive `Date.now()` with custom refresh rate\n- [usePerformanceNow](https://pikax.me/vue-composable/composable/date/performanceNow) : Returns reactive `performance.now()` with custom refresh rate\n\n### Format\n\n- [format](https://pikax.me/vue-composable/composable/format/format) - Reactive string format\n- [path](https://pikax.me/vue-composable/composable/format/path) - Retrieve object value based on string path\n\n### Breakpoint\n\n- [MatchMedia](https://pikax.me/vue-composable/composable/breakpoint/matchMedia) - reactive `MatchMedia`\n- [Breakpoint](https://pikax.me/vue-composable/composable/breakpoint/breakpoint) - reactive `breakpoints` based on `window.innerWidth`\n- [Chrome](https://pikax.me/vue-composable/composable/breakpoint/breakpointChrome) - reactive chrome breakpoints\n- [TailwindCSS](https://pikax.me/vue-composable/composable/breakpoint/breakpointTailwindCSS) - reactive TailwindCSS breakpoints\n\n### MISC\n\n- [sharedRef](https://pikax.me/vue-composable/composable/misc/sharedRef) - cross-tab reactive `ref`\n- [VModel](https://pikax.me/vue-composable/composable/misc/vmodel) - helper to wrap model update into a `ref` `[vue3 only]`\n- [injectFactory](https://pikax.me/vue-composable/composable/misc/injectFactory) - same as [inject](https://vue-composition-api-rfc.netlify.app/api.html#dependency-injection) but allows you to have a factory as default value\n- [interval](https://pikax.me/vue-composable/composable/misc/interval) - self-remove `setInterval` on unmount\n- [lockScroll](https://pikax.me/vue-composable/composable/misc/lockScroll) - `lock-scroll` component\n- [refDebounced](https://pikax.me/vue-composable/composable/misc/refDebounced) - debounces the update value of a `ref`\n\n### Storage\n\n- [WebStorage](https://pikax.me/vue-composable/composable/storage/webStorage) - Reactive access to `Storage API`, `useLocalStorage` and `useSessionStorage` use this\n- [storage](https://pikax.me/vue-composable/composable/storage/storage) - uses `localStorage` or on safari private it uses `sessionStorage`\n- [localStorage](https://pikax.me/vue-composable/composable/storage/localStorage) - Reactive access to a `localStorage`\n- [sessionStorage](https://pikax.me/vue-composable/composable/storage/sessionStorage) - Reactive access to a `sessionStorage`\n\n### Pagination\n\n- [Pagination](https://pikax.me/vue-composable/composable/pagination/pagination) - Generic reactive pagination controls\n- [Array Pagination](https://pikax.me/vue-composable/composable/pagination/arrayPagination) - Array pagination\n\n### Validation\n\n- [Validation](https://pikax.me/vue-composable/composable/validation/validation) - model based validation inspired by [vuelidate](https://vuelidate.js.org/)\n\n### i18n\n\n- [i18n](https://pikax.me/vue-composable/composable/i18n/i18n) - Simple i18n implementation with API inspired by [vue-i18n](https://github.com/kazupon/vue-i18n)\n\n### Intl\n\n- [dateTimeFormat](https://pikax.me/vue-composable/composable/Intl/dateTimeFormat) - Intl.DateTimeFormat\n- [numberFormat](https://pikax.me/vue-composable/composable/Intl/numberFormat) - Intl.NumberFormat\n- [currencyFormat](https://pikax.me/vue-composable/composable/Intl/currencyFormat) - CurrencyFormat with Intl.NumberFormat\n\n### Promise\n\n- [Promise](https://pikax.me/vue-composable/composable/promise/promise) - `Promise` reactive resolve and reject\n- [promiseLazy](https://pikax.me/vue-composable/composable/promise/promiseLazy) - Sugar for [usePromise](https://pikax.me/vue-composable/composable/promise/promise) `lazy:true`\n- [Cancellable Promise](https://pikax.me/vue-composable/composable/promise/cancellablePromise) - Allow to cancel promises\n- [Retry](https://pikax.me/vue-composable/composable/promise/retry) - Provides functionality to retry `promise`\n\n### Meta\n\n- [Title](https://pikax.me/vue-composable/composable/meta/title) - reactive `document.title`\n\n### State\n\n- [Timeline](https://pikax.me/vue-composable/composable/state/timeline) - Tracks variable history\n- [Undo](https://pikax.me/vue-composable/composable/state/undo) - Tracks variable history, to allow `undo` and `redo`\n- [valueSync](https://pikax.me/vue-composable/composable/state/valueSync) - syncs variables value, across multiple `ref`s\n\n### Web\n\n- [Fetch](https://pikax.me/vue-composable/composable/web/fetch) - reactive `fetch` wrapper\n- [WebSocket](https://pikax.me/vue-composable/composable/web/webSocket) - reactive `WebSocket` wrapper\n- [IntersectionObserver](https://pikax.me/vue-composable/composable/web/intersectionObserver) - reactive `IntersectionObserver`\n- [NetworkInformation](https://pikax.me/vue-composable/composable/web/networkInformation) - reactive `NetworkInformation` wrapper\n- [Online](\u003c[composable/web](https://pikax.me/vue-composable/composable/web)/online\u003e) - reactive `navigator.onLine` wrapper\n- [PageVisibility](https://pikax.me/vue-composable/composable/web/pageVisibility) - reactive `Page Visibility API`\n- [Language](https://pikax.me/vue-composable/composable/web/language) - reactive `NavigatorLanguage`\n- [BroadcastChannel](https://pikax.me/vue-composable/composable/web/broadcastChannel) - reactive `BroadcastChannel API`\n- [Geolocation API](https://pikax.me/vue-composable/composable/web/geolocation)\n- [CSS variables](https://pikax.me/vue-composable/composable/web/cssVariables) - reactive `CSS variables`\n- [Worker](https://pikax.me/vue-composable/composable/web/worker) - `Web Worker API`\n- [WorkerFunction](https://pikax.me/vue-composable/composable/web/workerFunction) - Webworker Function, offload a function to webworker\n- [share](https://pikax.me/vue-composable/composable/web/share) - WebShare API\n- [Clipboard](https://pikax.me/vue-composable/composable/web/clipboard) - Clipboard API\n\n### External\n\n\u003e New packages needed\n\n- [Axios](https://pikax.me/vue-composable/composable/external/axios) - [@vue-composable/axios](https://www.npmjs.com/package/@vue-composable/axios) reactive `axios` wrapper client\n- [makeAxios](https://pikax.me/vue-composable/composable/external/makeAxios) - [@vue-composable/axios](https://www.npmjs.com/package/@vue-composable/axios) wrap your `axios` instance\n- [useCookie](https://pikax.me/vue-composable/composable/external/useCookie) - [@vue-composable/cookie](https://www.npmjs.com/package/@vue-composable/cookie) `js-cookie` wrapper\n\n## Information\n\nThis is a monorepo project, please check [packages](packages/)\n\n## Devtools\n\nThere's some experimental devtools support starting from `1.0.0-beta.6`, only available for `vue-next` and `devtools beta 6`.\n\n- [devtools beta chrome](https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg)\n\n### Install plugin\n\nTo use devtools you need to install the plugin first:\n\n```ts\nimport { createApp } from \"vue\";\nimport { VueComposableDevtools } from \"vue-composable\";\nimport App from \"./App.vue\";\n\nconst app = createApp(App);\napp.use(VueComposableDevtools);\n// or\napp.use(VueComposableDevtools, {\n  id: \"vue-composable\",\n  label: \"devtool composables\"\n});\n\napp.mount(\"#app\");\n```\n\n### Component State\n\nTo add properties to the component inspector tab\n[ComponentState](https://github.com/vuejs/vue-devtools/blob/next/packages/api/src/api/component.ts#L68)\n\n```ts\nconst bar = \"bar\";\nuseDevtoolsComponentState(\n  {\n    bar\n  },\n  {\n    type: \"custom composable\" // change group\n  }\n);\n\nconst baz = () =\u003e \"baz\";\nuseDevtoolsComponentState({ baz });\n// no duplicates added by default\nuseDevtoolsComponentState({ baz });\n\nconst the = 42;\nuseDevtoolsComponentState({ the });\n// to allow multiple same key\nuseDevtoolsComponentState({ the }, { duplicate: true });\n\n// use a devtools api list directly\ninterface StateBase {\n  key: string;\n  value: any;\n  editable: boolean;\n  objectType?: \"ref\" | \"reactive\" | \"computed\" | \"other\";\n  raw?: string;\n  type?: string;\n}\nuseDevtoolsComponentState([\n  {\n    key: \"_bar\",\n    type: \"direct\",\n    value: \"bar\",\n    editable: true\n  },\n  {\n    key: \"_baz\",\n    type: \"direct\",\n    value: \"baz\",\n    editable: false\n  }\n]);\n\n// raw change\nuseDevtoolsComponentState((payload, ctx) =\u003e {\n  payload.state.push(\n    ...[\n      {\n        key: \"_bar\",\n        type: \"raw\",\n        value: \"bar\",\n        editable: true\n      },\n      {\n        key: \"_baz\",\n        type: \"raw\",\n        value: \"baz\",\n        editable: false\n      }\n    ]\n  );\n});\n```\n\n### Timeline events\n\nTo add timeline events:\n\n```ts\nconst id = \"vue-composable\";\nconst label = \"Test events\";\nconst color = 0x92a2bf;\n\nconst { addEvent, pushEvent } = useDevtoolsTimelineLayer(\n  id,\n  description,\n  color\n);\n\n// adds event to a specific point in the timeline\naddEvent({\n  time: Date.now(),\n  data: {\n    // data object\n  },\n  meta: {\n    // meta object\n  }\n});\n\n// adds event with `time: Date.now()`\npushEvent({\n  data: {\n    // data object\n  },\n  meta: {\n    // meta object\n  }\n});\n```\n\n### Inspector\n\nAllows to create a new inspector for your data.\n\n\u003e I'm still experimenting on how to expose this API on a composable, this will likely to change in the future, suggestions are welcome.\n\n```ts\nuseDevtoolsInspector(\n  {\n    id: \"vue-composable\",\n    label: \"test vue-composable\"\n  },\n  // list of nodes, this can be reactive\n  [\n    {\n      id: \"test\",\n      label: \"test - vue-composable\",\n      depth: 0,\n      state: {\n        composable: [\n          {\n            editable: false,\n            key: \"count\",\n            objectType: \"Ref\",\n            type: \"setup\",\n            value: myRefValue\n          }\n        ]\n      }\n    }\n  ]\n);\n```\n\n## Typescript\n\n`Typescript@3.x` is not supported, the supported version can be checked on [package.json](./package.json), usually is the latest version or the same major as `vue-3`\n\n## Contributing\n\nYou can contribute raising issues and by helping out with code.\n\nTests and Documentation are the most important things for me, because good documentation is really useful!\n\nI really appreciate some tweaks or changes on how the documentation is displayed and how to make it easier to read.\n\nTwitter: [@pikax_dev](https://twitter.com/pikax_dev)\n\n## Build\n\n```bash\n# install packages\nyarn\n\n# build and test for v2\nyarn build --version=2\nyarn test:vue2\n\n# build and test for v3\nyarn build\nyarn test\n```\n\n### New composable\n\n1. Fork it!\n2. Create your feature branch: `git checkout -b feat/new-composable`\n3. Commit your changes: `git commit -am 'feat(composable): add a new composable'`\n4. Push to the branch: `git push origin feat/new-composable`\n5. Submit a pull request\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)\n\n[now]: https://pikax.me/vue-composable/composable/date/now\n[date-now]: https://pikax.me/vue-composable/composable/date/dateNow\n[performance-now]: https://pikax.me/vue-composable/composable/date/performanceNow\n[pagination]: https://pikax.me/vue-composable/composable/pagination/pagination\n[array-pagination]: https://pikax.me/vue-composable/composable/pagination/arrayPagination\n[promise]: https://pikax.me/vue-composable/composable/promise/promise\n[retry]: https://pikax.me/vue-composable/composable/promise/retry\n[cancellable-promise]: https://pikax.me/vue-composable/composable/promise/cancellablePromise\n[debounce]: https://github.com/pikax/vue-composable\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikax%2Fvue-composable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpikax%2Fvue-composable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikax%2Fvue-composable/lists"}