A great way to structure and bootstrap VueJS + Vuetify + API projects

A great way to structure and bootstrap VueJS + Vuetify + API projects

There is no magic formula to create a perfect VueJS project, but definitely there are "best practices" that will make a better development workflow

A common question when we start a project is to decide where to put each software piece, how to organize the project's structure, which linter, code style, library to handle environment variable and so on.

I'd like to present to you a well structured VueJS project that focus on productivity, maintainability and perhaps a more intuitive one. In this way, rather than creating a huge discussion among all developers to decide where things take place, it has a great initial structure. Indeed, it promotes your team to focus on the business or the domain's problem/solution first.

DISCLAIMER: It's always a good idea, start from scratch and add each library or code as soon it is required, understand why each piece is necessary is extremely important, however, doing this all the time could be waste of time.

πŸ‘‰ Note: The links for more details, references and the source code are in the end.

WHY

  • Have a great initial structure and delivery the first feature faster
  • Have an organization that helps you have context separated in different files/folders

Main Features

  • Page inheritance
  • Routes
  • API Ready + API Mock
  • Linter + Code Style
  • Working examples
  • Easy to rename, change or even remove things
  • dotenv

Show me the code

Vue initial structure

Many of you might be familiar with the initial vue create my-project structure:

# vue create my-project
my-project
β”œβ”€β”€ babel.config.js
β”œβ”€β”€ package.json
β”œβ”€β”€ public
β”‚   β”œβ”€β”€ favicon.ico
β”‚   └── index.html
β”œβ”€β”€ README.md
└── src
    β”œβ”€β”€ App.vue
    β”œβ”€β”€ assets
    β”‚   └── logo.png
    β”œβ”€β”€ components
    β”‚   └── HelloWorld.vue
    └── main.js

Even though they keep things simple (KISS) which is great! Most of the time, we need to add a lot of things. The key here is, save time and avoid unnecessary discussions.

If you need a how to step by step for an initial VueJS project, I recommend this post here .

A better project structure

Below is the initial structure generate by this vue project template . Don't be scared, it's simpler than it seems and it is lean and few dependencies.

# vue init huogerac/crud-vuetify-structured-template my-project

my-project
β”œβ”€β”€ apiMock
β”‚   β”œβ”€β”€ db.json
β”‚   └── server
β”‚       β”œβ”€β”€ config.js
β”‚       └── index.js
β”œβ”€β”€ babel.config.js
β”œβ”€β”€ package.json
β”œβ”€β”€ .prettierrc.js
β”œβ”€β”€ .env
β”œβ”€β”€ public
β”‚   β”œβ”€β”€ favicon.ico
β”‚   └── index.html
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ api
β”‚   β”‚   β”œβ”€β”€ index.js
β”‚   β”‚   └── tasks.api.js
β”‚   β”œβ”€β”€ App.vue
β”‚   β”œβ”€β”€ assets
β”‚   β”‚   β”œβ”€β”€ 404_notfound.svg
β”‚   β”‚   └── 500_server_down.png
β”‚   β”œβ”€β”€ components 
β”‚   β”‚   β”œβ”€β”€ TaskCreateDialog.vue
β”‚   β”‚   β”œβ”€β”€ TaskUpdateDialog.vue
β”‚   β”‚   β”œβ”€β”€ AppBar.vue
β”‚   β”‚   β”œβ”€β”€ Footer.vue
β”‚   β”‚   β”œβ”€β”€ TaskCard.vue
β”‚   β”‚   └── TaskForm.vue
β”‚   β”œβ”€β”€ filters
β”‚   β”‚   └── dateFilter.js
β”‚   β”œβ”€β”€ main.js
β”‚   β”œβ”€β”€ mixins
β”‚   β”‚   └── ApiResponseMixin.vue
β”‚   β”œβ”€β”€ pages
β”‚   β”‚   β”œβ”€β”€ layouts
β”‚   β”‚   β”‚   └── Public.vue
β”‚   β”‚   └── public
β”‚   β”‚       β”œβ”€β”€ 404.vue
β”‚   β”‚       β”œβ”€β”€ 500.vue
β”‚   β”‚       └── Home.vue
β”‚   β”œβ”€β”€ plugins
β”‚   β”‚   └── vuetify.js
β”‚   β”œβ”€β”€ router
β”‚   β”‚   β”œβ”€β”€ index.js
β”‚   β”‚   └── public.routes.js
β”‚   └── settings.js
└── vue.config.js

Let's make it simpler to understand:

First we have the flow, from the url which can be the root / or some specific page, such as /about-me that is the entry point.

Basically, we have Route [1] that matches the URL and is related to one Page [2]. Pages are Vue Components too, however, they have a specific folder (pages)

components1.png

Then we have Pages X Components X Pure Components:

Everything are Vue Components too, Let's start with the Pure Components [3] (or DUMP), the key here is they are 100% visual, in another words, there is no call for external things or the API. Pure components use this.$emit to send events to others components.

Then we have the "non Pure Components", they are the SMART components where we make rules and calls to the API. The idea is keep the SMART components inside the src/pages

background-hashnode-vuejs-2.png

Here a little bit more details about each folder:

└── src
    β”œβ”€β”€ router             πŸ‘‰ #1 App routes
    β”‚   β”œβ”€β”€ index.js
    β”‚   └── tasks.api.js       πŸ‘‰ Routers by context
    β”œβ”€β”€ pages              πŸ‘‰ #2 App pages/views  ("SMART")
    β”‚   β”œβ”€β”€ layouts            πŸ‘‰ Pages bases
    β”‚   β”‚   └── Public.vue
    β”‚   └── public             πŸ‘‰ Pages by context
    β”‚       β”œβ”€β”€ 500.vue
    β”‚       └── Home.vue
    β”œβ”€β”€ components         πŸ‘‰ #3 VueJS components files ("DUMB")
    β”œβ”€β”€ api                πŸ‘‰ #4 API folder
    β”‚   β”œβ”€β”€ index.js
    β”‚   └── tasks.api.js       πŸ‘‰ API endpoints by context
    β”œβ”€β”€ mixins             πŸ‘‰ Anything used cross components
    β”‚   └── ApiResponse.vue
    β”œβ”€β”€ filters            πŸ‘‰ VueJS template filters
    β”‚   └── dateFilter.js
    β”œβ”€β”€ assets
    β”‚   └── some-image.jpg
    β”œβ”€β”€ plugins
    β”‚   └── vuetify.js
    β”œβ”€β”€ package.json
    β”œβ”€β”€ .prettierrc.js

There is also the apiMock folder which contains the API Mock and make your life easier without be dependent of a real API Backend (other NodeJS or Python application). Checkout the npm run api:mock defined inside the package.json, it starts the API Mock over the port 3001 and make available all data you add inside the apiMock/server/db.json available as API. Thanks the awesome json-server library.

Naming components

An idea is to use:

  • App or Base prefix for generic components (e.g. AppBar)
  • The prefix for one usage components (e.g. TheFooter)
  • "Something" prefix for group by context (e.g. UserResetPassword, TaskForm)

What's next

  • Checkout the repository crud-vuetify-structured-template for more details, run locally and see it running just with few commands
  • Contribute giving ideas and feedback, let's make this structure even better! Use the hashnode comments or directly the repository issues

I hope you've enjoyed this article. Special thanks to my friend Luiz OtΓ‘vio who helped tremendously in this structure.

Β