Frontend Shorts: Vue.js + Vanilla.js — Digital Dices

Ilona Codes - Apr 11 '20 - - Dev Community

Let me show you how you can implement a dice-rolling simulator in less than 30 minutes of your time on the front-end.

Currently, I am playing around with Vue.js. Despite the solution with VanillaJS, I will also present how to code it quickly with Vue.js too.

Let's walk through the process:

Traditionally, we are starting with writing HTML-tree to render two dices:

<!-- index.html | VanillaJS Implementation -->

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dice Rolling Simulator</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <div id="app" onclick="roll()">
        <div class="dice" data-dots>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>

        <div class="dice" data-dots>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <script src="index.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

There are 2 div-parents with the class .dice, it means there are 2 playing dices on the screen.

The data-dots is an attribute, which represents how many dots will be rendered on the dice after each roll.

The roll() function makes tapping work everywhere, so the user can make a roll upon a click easily.

You already know that you need to generate random numbers for each roll. And here we need to add JavaScript:

// index.js | VanillaJS Implementation

const dices = window.document.querySelectorAll('.dice');

const roll = () => {
    dices.forEach(dice => {
        const dots = Math.floor(Math.random() * 6) + 1;
        dice.setAttribute("data-dots", dots);
    })
};

// first initial roll for when the page loads
roll();
Enter fullscreen mode Exit fullscreen mode

We are going to roll 2 dices at the same time.

Then we need to loop through the dices with forEach method to simulate one of the six dice sides and randomize dice output after each roll: const dots = Math.floor(Math.random() * 6) + 1;

To render the output result, we set data-dots attribute to the corresponding value dots.

The template structure on Vue.js looks a bit differently, but not that much, let's compare:

<!-- index.html | Vue.js Implementation -->

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dice Rolling Simulator</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div id="app" v-on:click="roll">
        <div class="dice" 
            v-for="dice in dices" 
            v-bind:data-dots="dice.dots" 
        >
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <script src="./lib/vue-2.6.11.min.js"></script>
    <script src="./index.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode
// index.js | Vue.js implementation

const app = new Vue({
    el: '#app',
    data: {
        dices: [
            { dots: 1 },
            { dots: 1 },
        ]
    },

    mounted() {
    // first initial roll for when the component mounts
        this.roll();
    },

    methods: {
        roll() {
            this.dices.forEach(dice => {
                dice.dots = Math.floor(Math.random() * 6) + 1;
            });
        }
    }
});
Enter fullscreen mode Exit fullscreen mode

Every Vue application starts by creating a new Vue instance with the Vue function: const app = new Vue({ // options })

The mounting DOM-element called el; the data object includes the data structure that manages the state of our component.

Additionally, to data properties, Vue instances expose instance properties, hooks, and methods too.

For our example, we have to override the mounted hook to invoke initial "roll()" for when the user loads the page.

In methods, there is a simple method roll() to throw random numbers after each dice roll written in VanillaJS.

To handle click event in the browser to roll dices, v-on:click="roll" has been added to the Vue instance with the #app. To pass the data to the element, you have to bind with v-bind:data-dots="dice.dots".

Last but not least, to make it work appropriately according to the HTML mark-up and scripts, we need CSS-styles:

.dice {
    display: inline-block;
    position: relative;
    border: 3px solid black;
    width: 100px;
    height: 100px;
    margin: 0.5rem;
}

.dice > div {
    content: ' ';
    position: absolute;
    width: 20px;
    height: 20px;
    border-radius: 100%;
}

.dice[data-dots="1"] > :nth-child(1) {
    top: 40px;
    left: 40px;
    background-color: black;
}

.dice[data-dots="2"] > :nth-child(1) {
    top: 20px;
    left: 40px;
    background-color: black;

}

.dice[data-dots="2"] > :nth-child(2) {
    top: 50px;
    left: 40px;
    background-color: black;
}

/* ... see full file here: https://gist.github.com/ilonacodes/b4aef61073129f41fd99b802c7ce8d8c */
Enter fullscreen mode Exit fullscreen mode

It's not the full CSS-file, but here it is important to understand the styling pattern. The example above shows you how to style dots for one dot and two dots on the dice.

It means,

  • if we need to render one dot: .dice[data-dots="1"], we position inside the .dice class its first child: .dice[data-dots="1"] > :nth-child(1) according to position we have written for this selector;

  • if we need to render two dots on the dice: .dice[data-dots="2"] > :nth-child(1) and .dice[data-dots="2"] > :nth-child(2), we just add styles to the second child within the styles of the first child.

For rendering three dots on the dice:
.dice[data-dots="3"] > :nth-child(1), .dice[data-dots="3"] > :nth-child(2), .dice[data-dots="3"] > :nth-child(3)

For rendering four dots on the dice:
.dice[data-dots="4"] > :nth-child(1), .dice[data-dots="4"] > :nth-child(2), .dice[data-dots="4"] > :nth-child(3), .dice[data-dots="4"] > :nth-child(4)

And so on till the dice[data-dots="6"] included.

Dice Rolling Simulator

That's it for now. Let me know if you find these frontend code snippets useful or joyful for you.

Thank you for reading! 🙏

Code your best,
Ilona Codes

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player