Build a Blackjack Game with Vuejs — Part 1


Introducing beginners to Vuejs and Quasar by building a web-app for the popular casino game, Blackjack. The finished source code can be download here [LINK]. You may also like a more polished version here [LINK]

I. What is Vuejs

Launched in 2014, Vuejs takes on many elements from Angular but is shipped in a much more lightweight package. The core team maintaining Vuejs builds into their project lots of abstractions that simplifies many complex tasks. This helps Vuejs become a great choice for first framework of developers who are starting out.

A modern open source JavaScript progressive framework, Vuejs core libraries are intended for building user interfaces and single-page applications. Being progressive means Vuejs can be easily incorporated into your existing project, with little to no adjustment needed at other parts of your application. It means you could start building your projects with Vuejs, then progressively add more frameworks as your requirements grows.

On its own Vuejs can handle anything from a small blog to full-on SaaS. It is trusted by major players like: Gitlab; Grammarly; Alibaba; Codeship; Reuters; and many more.

II. What is Quasar

In this tutorial, we use Quasar, an excellent Vuejs framework with incredibly detailed documentation. This would help making sure beginners could get well optimized websites out of this tutorial. Instead of the usual skeleton app from elsewhere on the web.

Much like Vuejs simplifies many abstract programming concepts, Quasar automates and preconfigures many production; and development tasks. With only a few simple manual modifications and command lines, new developers could get fine-tuned applications to market in no time flat. The cherry on top for choosing Quasar is its build once ship everywhere capability. Whereas your project could be optimized and packaged to whatever platform of your choosing.

You should definitely learn more about this amazing framework. In my humble opinion, Quasar is among the best tools for beginners to get out of tutorial hell. Going from building Hello World apps to remarkably well-tuned applications in relatively short-time.

III. Setup and Project Structure

Thank to Quasar, our project structure can be setup in only a few command lines.

First install Quasar CLI:

npm install –g @quasar/cli

Then create a project folder with:

quasar create [your project name]

While Quasar is setting you up, you would need to select a few options for the framework to know what type of application you are building. Choosing the default options is fine, continue till Quasar finish setting up your project.

IV. Folders Structure

Public: this folder stores static files that would not interact too much with your code. In pretty all web applications you would find your website favicons files and manifest.json here. Those files are important for communicating your website content to search engines web crawlers. But during development you would rarely touch those files. Thus they can be safely ignored at this step.

Src: this folder stores pretty much everything that live in your application. Hence the name “src” short for source as in source codes. Each subfolder inside this main directory also has a role, and thus a reserved name:

· Assets:

A subfolder of your main folder src, this place houses assets such as images; sounds; videos; etc. Anything that need to be loaded, and/or manipulated by your codes, you put it here.

· Boot:

This folder is reserved for third party libraries, which you may add into your project. During the installation and setting up phrase, you would have been asked by Quasar, which additional features you want to add to your application. Had you selected any, their boot files would be located here.

· Components:

This folder is going to be your most frequently visited place. It houses all your application components. Pieces that come together create your product. Vuejs much like many modern frameworks stresses the use of modularity, for better performance and development ease.

· Css:

This folder would keep your styling for components and pages. You would find two files in it, one for global styling for your app the other for Quasar’s styling files. Quasar gives you options in customizing your app’s appearances, either traditional SCSS or its own customizable styling library. Of course, you would have the choice to style your components inside their source vue file as well. So it is really up to your own development style, centralized with global styling or decentralized by including tags: <styles> and/or <style lang=”scss” scoped> in each component source file.

· Layouts:

This folder houses special components that remain in your user interface even as the page changed. They usually composes of navigation bar; side bar; search bar; anything you want make available to your user at any time during their visit. You could specifies different layouts for different pages. You can dynamically load your layouts instead of statically, which affect web load-time performance as your project grows. Because our blackjack web-app is relatively simple we only use one layout here, so there would only have one file in this folder: “MainLayout.vue

· Pages:

This is where Quasar puts the vue files that are served to your user browsers to be viewed as pages in your application. In these files is where you suppose to arrange your components, into your designed interfaces. A page is different from a component in that it has a path or a route like “/about”, “/game”.

· Router:

This is where your router files lives. The files that direct your user interface which page to load for which path/route of your project.

V. Important Working files

We will now start building our blackjack game. At the end of this first part we will be able to choose how many decks of cards to play with, and how much money we would like to place as bet.


You don’t need much in this file, since our blackjack game is a single page application. There is no navigation panel; header or footer to add here. So remove the default code from Quasar and add this empty template for our main layout.


Our Index file would be the landing page for our visitors. In part I, we will implement the only function the landing page need to do, collect our users’ preference on the number of decks they want to play with. I know that this is not a very good game design decision, since most player wouldn’t care how many decks of cards is in the game, unless they plan to count cards. But I think it’s a perfect feature to teach you how Vue objects communicate with each other. An extremely useful knowledge when building more complex applications.

We will pass data from Index.vue to our first component Game.vue, which we will implement shortly below. So replace the code in your Index.vue with this:

Note that we have create two new properties inside our index object’s ‘data’ property. A number named ‘numOfDeck’, and a Boolean named ‘gameStarted’. gameStarted will be used as the signal to start the game. numOfDeck has default value as 1. It will be constructed in our ‘Game’ component, which we imported through:

import Game from ‘../components/Game’

components: { Game },

And included in the ‘components’ property of our object. Of course the component has not been built yet, so don’t start the server just yet.


Next we will create our first component, which is also our main working file in this project: Game.vue. It will stores all your game loop logics; data model; and methods. In part I, we will implement the player’s bankroll and placing bet mechanic. Our GUI will look something like this:

First let show you how to get data from Index.vue. Despite Index.vue being a page, it has the same system of properties that you could pass data from one component to another in any Vue application.

Vue object property is the simplest tool in sharing data between Vue objects. They often called props in most tutorials out there, even in the official Vuejs documentation. Think of them as useful custom attributes, that you could add to your components. Then in other components or pages, we could give these attributes values, static or dynamic user inputs. Hence passing data from one object to another. That’s it, it is that simple.

If you had read through the html code inside Index.vue, you would see that we’ve already done the second bit. Through the slider and preloading the game component:

The key concept of the code above is data binding. Please take careful notes here:

· V-model is a common directive in Vuejs. It bind the value generate by user input through <q-slider>, a Quasar built custom Vue component, to whatever number property of your object. In this case, it is numOfDeck.

· Index.vue numOfDeck property is use to preload Game.vue numOfDecks property.

· You could name the two properties more distinctively or the same as each other, but it would create difficulty in maintenance and bug hunting. So slight different versions of the same name is best.

Let implement the Game.vue component of our application. Create a file ‘Game.vue’ inside your component folder. You could remove whatever is currently there. Then paste these codes in:

Alright, there are quite a few things to unpack here. First let’s look at the html template, you would notice that apart from the standard html tags, there are a few new ones similar to the previously discussed <q-slider> tag. The prefix ‘q-‘marks all these new tags as Quasar built Vue components. They simplify many boilerplate codes and menial tasks. Take <q-btn> for example, if you read on its documentation, you will find out-of-the-box options to tailor the button shape; style; icons; etc. All is made easily available to developers through simple keywords extensions. This is the magic of Quasar.

I highly recommend you read up on these new tags on Quasar documentation page [LINK]. They helped me saved so much time and sanity in my works. I can’t imagine going back to vanilla Vuejs anymore.

Next, we will go through our new properties. They are name; props; data; mounted; and methods. The first one is self-explanatory, it’s the name you give your component. We have used this name to import the Game component in Index.vue.

Then come ‘props’ where all your object’s attributes lives. In our props, you will find numOfDecks, the attribute we give value to in our Index.vue page. Right below ‘props’ is ‘data’, where another set of attributes are stored. It can be quite confusing at first to see two properties of the same object doing essentially the same thing, storing variables. But all you have to remember in order to distinguish the two is their scopes. Variables or attributes or values in ‘props’ are global, hence we are able to access numOfDecks from Index.vue or anywhere else in your application. All you have to do is importing the Game component. While heroStatus inside ‘data’ is private to the Game component itself. No other object can access it.

Vue object props and data are quite a lot more complex than what mentioned in this tutorial. I highly recommend you to read more on this in order to fully understand Vue. As for this project, everything you need to know is in the above paragraph.

Continue to ‘mounted’, this properties is simple. It stores the codes which would run when the component or object is first loaded by clients or other objects. It is empty, because we do not need to load anything when Game is loaded at the moment. Later though, we would use ‘mounted’ and its two other cousins in controlling the game flow. For now, keep a small part of your mind for this type of special properties which control which codes get run when.

Finally is ‘methods’, if ‘data’ is used in storing private variables for your object, then ‘methods’ as the name implies store procedures that your object can perform. In it, you will find methods which could be used in our object’s template components like <q-btn>. As in, if users click this button run this code.

<q-btn label=”Place Bet” color=”white” text-color=”purple” class=”full-width” @click=”handlePlaceBet” />

Other properties can also use codes placed inside ‘methods’ as well. In next parts, we will use this feature in ‘mounted’ and more. At the moment, you can see four methods there. All of them are in plain simple JavaScript, I believe they are self-explanatory enough, that anyone who made it to this point would be able to understand the simple codes. So we would skip the explaining and move on to testing.

Open a Command Prompt, cd /d to your working directory (your project’s main folder), and type this command: quasar dev. After the codes have been successfully complied, you would see something like this on your browser at localhost:8080.

Is it hurting your eyes? It sure does to mine. Let’s change the background color to something more pleasant. Open your css/app.scss file.


This is where you would put your global styling. Paste in this code and save file:

body {

font-family: “Montserrat”;

background: #2F3652;

color: #fff;


And wait for your server to automatically recompile, the check your local host again. Much better? Like I mentioned before Quasar create two files in this css folder, both can be used to globally format your application. In this part we make sure that no matter which component is being loaded onto the user interface, its background would be of color #2F3652.


Alright, we are at the finishing stretch of part I. Congratulation for getting here! As you’d probably already seen our blackjack webapp is taking shape. We are able to dictate how many decks of cards to be played with and how much money to be bet on. But if you have been follow the tutorial closely and read all my code, you would notice something is missing. There is no notification popup when you’d have bet away the 5000 euro in the initial bankroll. This line of code cannot be run successfully, and it would give you an error in your browser console.

this.showNotification(‘Not enough money’)

Let’s open ‘quasar.conf.js’ file, it is located at the main directory of your project. Find this piece of code inside:

It requires the use of a Vue prototype injection. A new tool for Quasar Vue application to quickly and painlessly expand using plugins and custom objects. It is a cool feature of Quasar that is again take away a lot of the pain from developing Vue projects. It does come with a caveat though, because using it mean increasing your application dependencies and therefore maintenance effort.

Let finish our first part by adding the ‘Notify’ plugin to our project. Change the code at plugins to this:

// Quasar plugins

plugins: [‘Notify’]

You might need to stop and restart your server to see this take effect. If everything goes well, you will be able to see notification “‘Not enough money” popups when you ran out.

Thank you for following to the end. You can continue to part II soon.