{"id":16194195,"url":"https://github.com/ndabap/vue-best-practises","last_synced_at":"2025-03-19T04:30:41.897Z","repository":{"id":94724353,"uuid":"103852167","full_name":"ndabAP/vue-best-practises","owner":"ndabAP","description":"NOT MAINTAINED These recommendations should give you assistance to use Vue.js in a progressive and future-orientated way","archived":false,"fork":false,"pushed_at":"2019-08-15T06:58:53.000Z","size":35,"stargazers_count":18,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-08T14:32:19.940Z","etag":null,"topics":["vue","vue-router","vuejs","vuex"],"latest_commit_sha":null,"homepage":"","language":null,"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/ndabAP.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-17T18:30:57.000Z","updated_at":"2025-02-28T03:02:32.000Z","dependencies_parsed_at":"2023-04-14T10:47:37.683Z","dependency_job_id":null,"html_url":"https://github.com/ndabAP/vue-best-practises","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndabAP%2Fvue-best-practises","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndabAP%2Fvue-best-practises/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndabAP%2Fvue-best-practises/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndabAP%2Fvue-best-practises/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ndabAP","download_url":"https://codeload.github.com/ndabAP/vue-best-practises/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243968578,"owners_count":20376417,"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":["vue","vue-router","vuejs","vuex"],"created_at":"2024-10-10T08:18:27.373Z","updated_at":"2025-03-19T04:30:41.890Z","avatar_url":"https://github.com/ndabAP.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# NOT MAINTAINED Vue.js best practises\n\nThese recommendations should give you assistance to use Vue.js in a progressive and future-orientated way. They are focused around the core of the official Vue.js dependencies, that are the [vue-router](https://github.com/vuejs/vue-router), [vuex](https://github.com/vuejs/vuex) and [vue](https://github.com/vuejs/vue) itself.\n\n## Guidelines\n\nThe recommendations differ in their importance. Check the following table to get an overview.\n\nKeyword | Description\n------- | ------------------------------------------------------------------------------------\nShall   | Shall is used in a sense of must. Ignoring it can result into problems\nShould  | Should has a higher weight than may. It is the recommend approach\nMay     | May is used in a sense of optional. It doesn't make a difference for the application\n\n## Best practises\n\n### Shall\n\n#### You shall use getters/setters for your data properties\n\nMutating a property should be as explicit as possible. Violating it could lead to an unwanted property mutation if you need the property as read-only.\n\n```javascript\ncomputed: {\n  property () {\n    return this.$store.state.property\n  }\n}\n```\n\nYou have two possibilities to improve that.\n\nUse computed getters/setters:\n\n```javascript\ncomputed: {\n  property: {\n    get () {\n      return this.$store.state.property\n    },\n\n    set (property) {\n      this.$store.commit('UPDATE_PROPERTY', property)\n    }\n  }\n}\n```\n\nUse Vuex [getters](https://vuex.vuejs.org/en/getters.html):\n\n```javascript\ngetters: {\n  property: state =\u003e {\n    return state.property\n  }\n}\n```\n\n[Back to top](#vuejs-best-practises)\n\n#### You shall use `Vue.set` and `Vue.delete` to mutate/delete properties/array keys\n\nSince Vue.js [can't detect property additions or deletions](https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats), you sould always use `Vue.set` to add and `Vue.delete` to delete properties or array keys. This is especially necessary when setting or deleting an array index or an object property. Please note: This won't be necessary in future versions.\n\n[Back to top](#vuejs-best-practises)\n\n#### You shall use pure functions\n\nIn Vue.js, many click directives should be handlers. Handlers do a couple of things. They should call other functions instead of combining the whole logic, which can lead to unpure functions with unwanted side effects. It's pretty easy to overlook that. Given a common example:\n\n```js\nsetIsVisibleModal (isVisibleModal) {\n  this.isVisibleModal = isVisibleModal\n  if (isVisibleModal === false) this.setIsVisibleModalButton(true)\n}\n```\n\nThis function does two things, even so the function name clearly coerces you to do only one thing. It's easier and more testable to use a handler instead, like showed here:\n\n```js\nmodalHandler (isVisibleModal) {\n  this.setIsVisibleModal(isVisibleModal)\n  if (isVisibleModal === false) this.setIsVisibleModalButton(true)\n}\n```\n\n[Back to top](#vuejs-best-practises)\n\n### Should\n\n#### You should handle HTTP requests at Vuex actions only\n\nHTTP requests should be independent from components. The underlying protocol, URI or route may change and you have to rewrite code at multiple places. It is better to have API-related operations at a centralized place instead of doing HTTP requests at the component level.\n\n[Back to top](#vuejs-best-practises)\n\n#### You should use component lazy loading\n\nWhen you import a component the usual way, it gets loaded upfront, regardless of if it's needed. You can prevent that behavior with a function.\n\n```javascript\nconst Component = () =\u003e import('./Component')\n```\n\n[Back to top](#vuejs-best-practises)\n\n#### You should always define methods instead of cluttering hooks\n\nIf you need to setup up something during one of the hooks upfront, you should define a method instead of writing everything into the hook. With that, you can easily reinvoke the method later if necessary.\n\n[Back to top](#vuejs-best-practises)\n\n#### You should use Vuex strict mode\n\nThe Vuex is the centralized state of your application. To reason about state mutations, you must be aware of changes in an exact manner. When the strict mode is enabled and the state is mutated outside of a mutation handler, an error will be thrown.\n\n[Back to top](#vuejs-best-practises)\n\n#### You should not use `Vue.parent`\n\nIn general, components should be loosely coupled. However, there are situations where components can also be tightly coupled. If you have a dedicated mother-child-relationship, it is perfectly okay to use `Vue.parent` to access the mother component from the child. Nevertheless, if components can stand on their own, you shouldn't use it. It could be that the relationship get's interrupted and the child component is wrapped around another component which makes `Vue.parent` useless.\n\n[Back to top](#vuejs-best-practises)\n\n#### You should not use watchers `deep: true`\n\nUsing `deep: true` at a watcher leads to heavy calculations because Vue.js has to recursively check for property changes. It's better to use an explicit getter instead and watch for it.\n\n[Back to top](#vuejs-best-practises)\n\n#### You should follow an entity based workflow\n\nUsing entities as component names can heavily simplify reasoning about your application. A component is responsible for doing one thing and the name should reflect that. Therefore, you may end up using names like `UserGet`, `ProductPatch` or `ProductPost`. For common logic use mixins. Furthermore, your states should be an image of your server API. Try avoiding abstraction of your API.\n\n[Back to top](#vuejs-best-practises)\n\n#### You should let mother components handling errors\n\nConsider a product page with a container component holding product components with another subcomponent loading product images. Thus, the responsibility chain goes down from the container component to the product component to the product images component. If there is an error with the product images, let the product component handle it. If the product component crashes, let the container decide what to do. This guarantees that the component with the most knowledge makes decisions.\n\n[Back to top](#vuejs-best-practises)\n\n### May\n\n#### You may use a state constructor\n\nYou might find yourself reseting a Vuex state. Instead of setting verbosely every property of the state, define a state constructor instead. To do so, wrap the state into an arrow function and use `Object.assign` to reset the state.\n\n```javascript\nconst stateConstructor = () =\u003e ({\n  entity: ''\n})\n```\n\nMutations:\n\n```javascript\nRESET_ENTITY (state) {\n  Object.assign(state, stateConstructor())\n}\n```\n\n[Back to top](#vuejs-best-practises)\n\n#### You may not always use state managament for a component\n\nMost times, a component is a seperated, isolated unit of your application. Therefore, there is no need for such a component to be accessible from the outside or the other way around. You can save a lot of state managament if you ask yourself some questions:\n\n- Do I need the components data or state elsewhere?\n- Does an other component must mutate the components behaviour?\n- Do I need the component elsewhere?\n\nYou may end up putting parts of your component into the store and the rest into the component.\n\n[Back to top](#vuejs-best-practises)\n\n#### You may use upper-case module names\n\nTo distinguish between modules and entities, you may use an upper-case module name. If you have many nested modules, this prevents you from mutating the root state, rather than a dedicated object for the entity. To use an upper-case namespace, simply define your modules like this:\n\n```js\nnew Vuex.Store({\n  modules: {\n    User: user,\n    Product: product,\n    Basket: basket\n  }\n})\n```\n\n[Back to top](#vuejs-best-practises)\n\n#### You may follow these naming conventions\n\nVue.js provides several varying APIs for DOM and state mutations or event communications. Since you decide about the interface names (like methods, events or DOM elements), a consistent naming convention is recommended. \n\n##### Components\n\n| Entity              | Example            |\n|---------------------|--------------------|\n| Component file name | `SearchBar`        |\n| Component           | `\u003csearch-bar/\u003e`    |\n| Events              | `make-user-visible`|\n| Mixin file name     | `SearchBarMixin`   |\n| Mixin               | `SearchBarMixin`   |\n| Props               | `:is-red=\"true\"`   |\n| References          | `user-post`        |\n\n##### Router\n\n| Entity      | Example          |\n|-------------|------------------|\n| Route name  | `DashboardIndex` |\n\n##### Vuex\n\n| Entity             | Example          |\n|--------------------|------------------|\n| Module file name   | `user.module`    |\n| Module             | `User`           |\n| Mutation file name | `user.mutations` |\n| Mutation functions | `SET_USER`       |\n| Action file name   | `user.actions`   |\n| Action functions   | `postUser`       |\n| State file name    | `user.state`     |\n| State properties   | `isUserVisible`  |\n\n[Back to top](#vuejs-best-practises)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndabap%2Fvue-best-practises","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fndabap%2Fvue-best-practises","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndabap%2Fvue-best-practises/lists"}