Quick Introduction to Vue.js — Super Mario Pixel Art
I’ve been asked a lot recently why we chose to implement our company’s first product in Vue.js. Not everyone has had a chance to explore Vue.js, so I thought it would be helpful to write a quick introduction to Vue.js by providing an example.
Drawing graphics may not be the most popular use case for Vue.js, but in this post, I wanted to give an example that I hoped others would find fun — Super Mario pixel art (inspired by Data Pixels), which draws with a pixel art and updates colors utilizing the reactivity of Vue.js when a pixel is clicked. You can find the entire code in my repository.
Planning
Before starting to code, I planned on constructing two Vue components to implement this graphic:
Pixel is a component, pixel.vue, taking options of RGB value and a size of pixel. It is a div
(instead of HTML canvas
element) and will emit an event when it is clicked to notify its parent component.
Canvas (canvas.vue) is a container that initializes the pixel components based on a 2-dimensional array with colors of each pixel.
pixel.vue
.vue
file can contains blocks of template, JavaScript, and CSS styles, so all of the necessary code for a component can exist in a single file.
In the script
tag, color (background color)
and size(pixel size)
are required properties (props) passed when the component is initialized. If it is not necessary to specify type
and required
in props
, it can be simplified to props: ['color', 'size']
. The values of properties are applied to pixelStyle()
computed property, which is bound to div.style
. If the value of color
property changes, it will propagate to the template through the computed property and the background of div.l-pixel
will be updated. v-bind:
(full syntax) or :
(shorthand) is used to bind a property or data in a template. The propagation is:
color change in canvas.vue >>> "color" in "props" in pixel.vue >>> "pixelStyle()" in "computed" >>> style attribute of "div.l-pixel" in "<template>"
v-on:
(full syntax) or @
(shorthand) is used to bind an event handler, and the click event of div.l-pixel
is bound to onPixelClick
in methods. The method will emit pixel-click
event with its color information, which a canvas component will listen to.
main.js
The main JavaScript file initializes the canvas.vue component, and here, we can see data provided for canvas.vue properties. this.pixelData
contains arbitrary color names of pixels and this.colors
is a color dictionary (JavaScript object) to include RGB values. (It can be improved by creating class Color,
which contains both the color name and RGB information.)
canvas.vue
It renders pixels with pixelData
passed from main.js
using v-for
.
<div v-for="(row, rowIndex) in pixelData" :key="rowIndex" :style="{height: pixelSize}">
<n-pixel v-for="(col, colIndex) in row" :key="colIndex" :color="colors[col]"
:size="pixelSize" @pixel-click="onPixelClick">
</n-pixel>
</div>
The pixel
component is registered with component: { NPixel },
which is an equivalent of components: {'n-pixel': NPixel}
, and the prefix n-
is used to prevent from a component name conflict just in case that pixel
is already registered as a global component.
In the <n-pixel v-for
, col
is a color name (i.e. “C”, “_”) which comes from main.js
and :color="colors[col]"
sends a RGB value(i.e. “255, 255, 255”) to a pixel
component. colIndex
is the index of current item (0, 1, 2, …). It is passed to the key
attribute, which Vue.js requires a unique value for v-for
.
@pixel-click="onPixelClick"
listens to the pixel-click
event from pixel
component and onPixelClick
changes a color in a dictionary (JavaScript object, this.colors
, instead of looping through the whole 2-dimensional array this.pixelData
, and by reactivity, the background colors of pixels get updated!
Next
If you want to explore Vue.js further, I would recommend reading some of their awesome documents. There is also a great free series of videos — Learn Vue 2: Step By Step in Laracast. In my opinion, it’s always helpful to write a small application to understand a library or a framework better. You can find an interesting subject or convert a part of your previous code to a new library. While it’s always helpful to read documents to learn more, the benefits and drawbacks of different libraries or frameworks are often easier to see when you start writing your code.