Quasar Framework is an amazing Vue.js framework providing not only extensive set of well-designed UI components, but also basic project structure, multiple build targets and plenty of other developer-friendly features.
Today I want to show you how to set up a Quasar Framework project that has:
- Support for Typescript
- Support for class-based Vue components
- Support for class-based Vuex modules
To start your journey with Quasar Framework, its recommended that you globally install the Quasar CLI by running the command:
After it is installed, navigate to the directory in which you want to create the project. Now it’s time to use the Quasar CLI to set things up for us:
This will start the new project wizard where you have to provide some information:
Project name- is simply your development project name. In this tutorial we’ll leave it as it is suggested.
Project product name- is the official name of the application you’re building. In this tutorial we’ll input:
My New Project
Project description- is simply a short description of your project. You can leave it empty. In this tutorial we’ll input:
A brand new project.
Author- just input your name or nickname or leave it empty
Pick your favourite CSS preprocessor- this setting won’t affect any future steps of this tutorial so choose what you’re familiar with. In this tutorial I’ll choose the most recommended option:
Sass with indented syntax
Pick a Quasar components & directives import strategy- when using Vue components provided by the Quasar Framework, you’ll need to import them first. Remember that you can always change this setting later in the
quasar.config.js. There are a couple of options to choose from:
Auto-import in-use Quasar components & directives- this is a nice feature that lets the framework itself figure out what to import. Unfortunately, at the moment of writing this tutorial, this functionality doesn’t work with Typescript, so we can’t use it.
Manually specify what to import- this is the more tedious way of development, because it requires you to manually specify which components and directives you are using. You register them in the
quasar.config.jsfile. We’ll go with this option in this tutorial because it makes the application as light as possible.
Import everything from Quasar- this imports absolutely everything there is in Quasar. It’s convenient for development but the resulting build also includes everything, so the app is huge.
Check the features needed for your project- here we can select some additional features that are integrated into the Quasar Framework. In this tutorial, we’ll select everything besides the
IE11 support. Remember that you select/deselect options using spacebar and go to the next step using the
ESLint- a must have for a healthy code base
Vuex- a Vuex store that we will use as the introduction to this tutorial suggests
Axios- a promise based HTTP client
Vue-i18n- a translations solution for Vue projects
Pick an ESLint preset- pick an ESLint preset of your choice. I recommend the
Airbnbpreset as it goes well with Typescript and enforces some good practices.
Cordova/Capacitor id- if you plan building the project as a mobile app, input the Cordova or Capacitor ID. If not, leave it default (as in this tutorial).
Should we run 'npm install' for you?- Choose whatever “Yes” option you prefer.
After this the whole project should be automatically generated and all dependencies downloaded. You can go to the newly created project directory and run the application in development mode with the command:
Quick project overview
A Quasar project looks similar to most Vue.js projects. In the root folder there are
README.md and plenty of config files. The
quasar.conf.js is the main Quasar Framework config file where you specify used plugins, icon sets, components, directives, webpack options and various build options.
Next to those files is the
src directory with quite a typical structure with the
index.template.html as a main component and base HTML template.
boot directory contains some code related to plugins that runs before Vue instance start running. It’s a perfect place to run some
components directory is intended to contain your Vue components, but it’s completely optional. The
layouts directory is intended to contain application layout Vue components. Quasar has its own
QLayout component which allows you to quickly create familiar app layouts and has support for pages (the
QPage component), which reside in the
pages directory. This generated project is a simple example of the
QLayout and the
QPage components relation as well as their configuration in the Vue router, which is situated in the
There is also the
store directory which contains a Vuex store with an example of a Vuex module.
Adding Typescript support
Now it’s time to finally add Typescript support to the project. The Quasar team created a handy extension to the Quasar Framework that automatically upgrades your project to Typescript. To install it just run the command:
During the installation process the script will ask you a couple of questions:
Please choose how to derive webpack- choose the recommended option
Rename .js files to .ts- we are operating on a fresh Quasar project so it won’t pose any problems - choose Yes
Will you use VSCode for this project?- it’s up to you
Generate Prettier configuration- if you’re planning on using Prettier, then definitely Yes
Overwrite ".eslintrc.js"- if you’re asked this question, choose
If you’ll try to run the project using the
quasar dev command it will run the app but with two errors:
Typescript isn’t happy about those two files. After changing their extensions to
.ts they are checked more strictly. Let’s quickly fix those errors.
src/boot/i18n.ts file and add two lines above the default export:
@ts-ignore comment forces the typescript linter to ignore the fact, that the
app argument is of type
any (which is prohibited). The
eslint-disable-next-line @typescript-eslint/ban-ts-ignore comment forces the typescript linter to ignore the rule to not allow usage of
@ts-ignore. It’s not the most elegant solution, but it’s enough in this case since you probably won’t be needing to change it anyway.
Now let’s fix the problem with the store definition in the
src/store/index.ts file. Open it and simply make sure that the
strict property will get the
boolean value by comparing it to the
Again, not very elegant, but it works. Now the project should run flawlessly.
Using class based Vue components
Ok. We have Typescript support, but all Vue components are still written the usual Vue way. To add support for class-based Vue components install 2 additional packages:
Install using npm:
or using Yarn:
Those two packages allow us to fully use our new powers of Typescript decorators. Let’s convert all components that exist in the project.
We need to change only the
Here we needed only to import the
Component decorator and change the component into class.
The name of the component is now defined solely by the class name.
This is basically the same process as with the
Here we have an example of a component with simple data. In a class-based Vue component, data is represented just by class field:
And that’s all it took. If you want to learn more about class based Vue components, you can look into the two packages that we’ve just installed:
Using class based Vuex modules
The next step to enjoy the full glory of Typescript is to use class-based Vuex modules. It not only makes them more readable, but also way easier to use, as Typescript will know all the data types. Let’s install the npm package that we need:
Install using npm:
or using Yarn:
Now, delete the existing example Vuex module by removing whole
src/store/module-example directory and fix the store declaration in
Instead of exporting the function that creates the Vuex store and importing modules there, we are creating a simple store instance here. This will easily let us create modules in any place we want.
Let’s create a
Layout module as an example of a class-based Vuex module. It will store the layout’s
Create a file
LayoutStoreModule.ts in the
First we’re importing all needed classes from the
vuex-module-decorators package and the store we created previously.
Next is the declaration of the module along with the
@Module decorator that specifies some details:
dynamic: true- this make it a dynamic module, which means that you don’t have register it in the store itself
name: 'layout'- this specifies a namespace of this module, so internally all module’s mutations, actions etc. will be prefixed with it
namespaced: true- this marks a module as a namespaced module
store: Store- here we are linking the module to the store we created earlier
Then we create a module state
leftDrawerOpen with a default value. It’s simply a class field. Next we create a mutation that sets the
leftDrawerOpen state. Below it there are two actions that allows us to set and toggle the state.
And that’s it when it comes to store creation. Now let’s use it in the
MyLayout.vue component. First we are going to modify the script part of the file:
We started by importing the
getModule function that lets us get the dynamic module. Then we also imported the module class itself.
Inside the component we got rid of the
leftDrawerOpen field and created the
store field instead that will hold the Vuex module that we got from
Then we declared a computed property (
get leftDrawerOpen()) that gets the store’s state. We also created the setter (
set leftDrawerOpen(value: boolean)) for this computed property so that it works well with the
QDrawer component that might try to change the
v-model if someone clicks outside the opened drawer. Here we used the module’s action to set the state.
In the template, we don’t have to touch the
v-model of the
QDrawer component, as it’s still the same name. We don’t even have to change the
@click event of the
QBtn that opens/closes the drawer. But if we want to, we can use the
toggleLeftDrawer action here in the template:
If you want to learn more about class-based Vuex modules, take a look at the package we’ve just installed: vuex-module-decorators website
It’s not only easy to configure the Quasar project to work well with TypeScript, but it’s also fun to use class-based Vue components and class-based Vuex modules. I hope this will help some who are starting out with Quasar and Typescript.