{"id":13486872,"url":"https://github.com/michaelolof/vuex-class-component","last_synced_at":"2026-02-03T10:37:14.138Z","repository":{"id":33958397,"uuid":"163118174","full_name":"michaelolof/vuex-class-component","owner":"michaelolof","description":"A Type Safe Vuex Module or Store Using ES6 Classes and ES7 Decorators written in TypeScript.","archived":false,"fork":false,"pushed_at":"2022-12-30T04:31:59.000Z","size":1430,"stargazers_count":216,"open_issues_count":46,"forks_count":21,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-10-04T13:48:50.149Z","etag":null,"topics":["es7-decorators","typesafe","typesafe-vuex","typescript","vue-state-manager","vuex","vuex-class","vuex-class-component","vuex-manager","vuex-modules","vuex-store","vuex-ts","vuex-typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michaelolof.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-25T23:50:26.000Z","updated_at":"2025-07-07T06:56:54.000Z","dependencies_parsed_at":"2023-01-15T03:36:54.897Z","dependency_job_id":null,"html_url":"https://github.com/michaelolof/vuex-class-component","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/michaelolof/vuex-class-component","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvuex-class-component","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvuex-class-component/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvuex-class-component/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvuex-class-component/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelolof","download_url":"https://codeload.github.com/michaelolof/vuex-class-component/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelolof%2Fvuex-class-component/sbom","scorecard":{"id":641429,"data":{"date":"2025-08-11","repo":{"name":"github.com/michaelolof/vuex-class-component","commit":"0faf428441f21f5a27f9dbacf23aaf5306b9628a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":2,"reason":"Found 5/21 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"80 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-vh7m-p724-62c2","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-h9rv-jmmf-4pgx","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-5j4c-8p2g-v4jx","Warn: Project is vulnerable to: GHSA-g3ch-rx76-35fx","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T10:53:01.179Z","repository_id":33958397,"created_at":"2025-08-21T10:53:01.180Z","updated_at":"2025-08-21T10:53:01.180Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29041776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T10:09:22.136Z","status":"ssl_error","status_checked_at":"2026-02-03T10:09:16.814Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["es7-decorators","typesafe","typesafe-vuex","typescript","vue-state-manager","vuex","vuex-class","vuex-class-component","vuex-manager","vuex-modules","vuex-store","vuex-ts","vuex-typescript"],"created_at":"2024-07-31T18:00:52.374Z","updated_at":"2026-02-03T10:37:14.116Z","avatar_url":"https://github.com/michaelolof.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Vuex Class Component\nA Type Safe Solution for Vuex Modules using ES6 Classes and ES7 Decorators that works out of the box for TypeScript and JavaScript.\n\n## Installation\n```\n$ npm install --save vuex-class-component\n```\n\n## New API\nThe goal of the new API is to reduce the decorator overhead and \nhttps://github.com/michaelolof/vuex-class-component/issues/27\n\nHow we normally define Vuex Stores.\n```js\n// user.vuex.ts\nconst user = {\n  namespace: true,\n  state: {\n    firstname: \"Michael\",\n    lastname: \"Olofinjana\",\n    specialty: \"JavaScript\",\n  },\n  mutations: {\n    clearName(state ) {\n      state.firstname = \"\"; \n      state.lastname = \"\";\n    } \n  },\n  actions: {\n    doSomethingAsync(context) { ... }\n    doAnotherAsyncStuff(context, payload) { ... }\n  },\n  getters: {\n    fullname: (state) =\u003e state.firstname + \" \" + state.lastname,\n    bio: (state) =\u003e `Name: ${state.fullname} Specialty: ${state.specialty}`,\n  }\n}\n```\n\n```ts\nimport { createModule, mutation, action, extractVuexModule } from \"vuex-class-component\";\n\nconst VuexModule = createModule({\n  namespaced: \"user\",\n  strict: false,\n  target: \"nuxt\",\n})\n\nexport class UserStore extends VuexModule {\n\n  private firstname = \"Michael\";\n  private lastname = \"Olofinjana\";\n  specialty = \"JavaScript\";\n  \n  @mutation clearName() {\n    this.firstname = \"\";\n    this.lastname = \"\";\n  }\n\n  @action async doSomethingAsync() { return 20 }\n\n  @action async doAnotherAsyncStuff(payload) { \n    const number = await this.doSomethingAsyc();\n    this.changeName({ firstname: \"John\", lastname: \"Doe\" });\n    return payload + this.fullName;\n  }\n\n  // Explicitly define a vuex getter using class getters.\n  get fullname() {\n    return this.firstname + \" \" + this.lastname;\n  } \n\n  // Define a mutation for the vuex getter.\n  // NOTE this only works for getters.\n  set fullname( name :string ) {\n    const names = name.split( \" \" );\n    this.firstname = names[ 0 ];\n    this.lastname = names[ 1 ];\n  }\n  \n  get bio() {\n    return `Name: ${this.fullname} Specialty: ${this.specialty}`;\n  }\n}\n\n// store.vuex.ts\nexport const store = new Vuex.Store({\n  modules: {\n    ...extractVuexModule( UserStore )\n  }\n})\n\n// Creating proxies.\nconst vxm = {\n  user: createProxy( store, UserStore ),\n}\n```\n\nOn the surface, it looks like not much has changed. But some rethinking has gone into how the libary works to make for a much better developer experience.\n\n## More Powerful Proxies\nWith the `strict` option set to `false` we can enable greater functionality for our proxies with automatic getters and setters for our state.\\\nFor Example: \n```ts\nvxm.user.firstname // Michael\nvxm.user.firstname = \"John\";\nvxm.user.firstname // John\n\nvxm.user.fullname // John Olofinjana\nvxm.user.fullname = \"Mad Max\";\nvxm.user.fullname // Mad Max\nvxm.user.firstname // Mad\nvxm.user.lastname // Max\n```\n\nNotice that we didn't have to define a mutation to change the `firstname` we just set the state and it updates reactively. This means no more boilerplate mutations for our state, we just mutate them directly.\n\nThis also opens up new possibilities in how we consume stores in Vue components.\nExample\n```html\n\u003c!-- App.vue --\u003e\n\u003ctemplate\u003e\n  \u003cdiv class\u003e\n    \u003cinput type=\"text\" v-model=\"user.firstname\" /\u003e\n    \u003cdiv\u003eFirstname: {{ user.firstname }}\u003c/div\u003e\n\n    \u003cbutton @click=\"user.clearName()\"\u003eClear Name\u003c/button\u003e\n    \u003cdiv\u003eBio: {{ user.bio }}\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\n  import { vxm } from \"./store\";\n\n  export default {\n    data() {\n      return {\n        user: vxm.user,\n      }\n    }\n  }\n\u003c/script\u003e\n```\n\nNotice how much boilerplate has been reduced both in defining our vuex stores and also in using them in our components.\nAlso notice we no longer need functions like `mapState` or `mapGetters`.\n\n## Implementing More Vuex Functionality\nVuex today has additional functionalities like `$watch` `$subscribe` and `$subScribeAction` respectfully.\n\nThis also possible with `vuex-class-component`\n```ts\n// Watch getters in Vue components\nvxm.user.$watch( \"fullname\", newVal =\u003e { \n  console.log( `Fullname has changed: ${newVal}` )\n});\n\n// Subscribe to mutations in Vue components \nvxm.user.$subscribe( \"clearName\", payload =\u003e {\n  console.log( `clearName was called. payload: ${payload}` )\n});\n\n// Subscribe to an action in Vue components\nvxm.user.$subscribeAction( \"doSomethingAsync\", {\n  before: (payload :any) =\u003e console.log( payload ),\n  after: (payload :any) =\u003e console.log( payload ),\n})\n```\n\nWe can even do better with Local watchers and subscribers.\n\n```ts\nconst VuexModule = createModule({\n  strict: false,\n  target: \"nuxt\",\n  enableLocalWatchers: true,\n})\n\nexport class UserStore extends VuexModule.With({ namespaced: \"user\" }) {\n  \n  firstname = \"John\";\n  lastname = \"Doe\";\n  @mutation changeName( name :string ) { ... }\n  @action fetchDetails() { ... }\n  get fullname() {\n    return this.firstname + \" \" + this.lastname;\n  }\n\n  $watch = {\n    fullname( newValue ) { console.log( `Fullname has changed ${newValue}` },\n  }\n\n  $subscribe = {\n    changeName( payload ) {\n      console.log( `changeName was called with payload: ${payload}`)\n    }\n  }\n\n  $subscribeAction = {\n    fetchDetails( payload ) {\n      console.log( `fetchDetails action was called with payload: ${payload}` )\n    }\n  }\n\n}\n```\n\n\n\n## SubModules Support \nTo use submodules\n```ts\n  const VuexModule = createModule({\n    strict: false\n  })\n\n  class CarStore extends VuexModule.With({ namespaced: \"car\" }) {\n    @getter noOfWheels = 4;\n\n    @action drive() {\n      console.log(\"driving on\", this.noOfWheels, \"wheels\" )\n    }\n  }\n```\nWe could use this sub module in a class\n```ts\n  class VehicleStore extends VuexModule.With({ namespaced: \"vehicle\" }) {\n    car = createSubModule( CarStore );\n  }\n```\nNow you can easily use in your Vue Components like:\n```ts\n  vxm.vehicle.car.drive() // driving on 4 wheels\n```\n\n## JavaScript Support\nFrom version `1.5.0` JavaScript is now supported fully.\nTo use vuex-class-component in your JavaScript files, ensure your babel.config.js file has the following plugins:\n```js\nmodule.exports = {\n  ...\n  plugins: [\n    [\"@babel/plugin-proposal-decorators\", { \"legacy\": true }],\n    [\"@babel/plugin-proposal-class-properties\", { \"loose\" : true }]\n  ]\n}\n```\nAnd then use as follows\n```js\nimport { Module, VuexModule, getter, action } from \"vuex-class-component/js\";\n```\n\n## NuxtJS Support\nFrom verison `1.6.0` Nuxt is also supported.\nTo use `vuex-class-component` with Nuxt, You add a `target` property to the @Module decorator and set it to `\"nuxt\"`.\n```js\nexport class UserStore extends createModule({ target: \"nuxt\" }) {\n  ...\n}\n```\n\n## See Old API\n[Old API \u003e](old-api-readme.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelolof%2Fvuex-class-component","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelolof%2Fvuex-class-component","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelolof%2Fvuex-class-component/lists"}