Vue describes itself as approachable, versatile and performant. Seems cool. So I decided to try it out. For this tutorial I created a Blackboard single page application to test run this JavaScript framework. The user interface is poor to say the least but it has some cool features without using a database. You can enter text in a small text box. You can then resize the text and save the page and created a new page. The text is show on the “blackboard” much larger than the textbox. You can review your saved pages create more pages.

As far as user interface goes while researching Vue I learnt about Vuetify.js. It is a great framework to add material styles to your app. You can learn more about that here. I didn’t go further because this was just a beginner overview. Also bootstrap as a Vue plugin or Vue has a bootstrap plugin. Check it out here.
Getting Started
To get started I searched out a starter template of course. I found this one using webpack https://github.com/vuejs-templates/webpack. And followed the instructions. Note you can find my code here.
$ npm install -g vue-cli
$ vue init webpack my-project
$ cd my-project
$ npm install
$ npm run dev
So once you have node and npm installed you should be good to go. This installed the project for you and gets you started. However if you’re using my completed app as your template you can do the following.
git clone https://github.com/wyntonfranklin/blackboard-vue-tutorial.git
npm install -g vue-cli // make sure vue-cli is installed
cd blackboard-vue-tutorial
npm install
npm run dev
The important part of the above is to ensure you have vue-cli installed globally. The dependencies will be handled with npm install command.
Directory Structure
build/
config/
src/
assets/
components/
router/
App.vue
main.js
Main.js
The main.js has the start up code for you Vue application. It creates a Vue instance and registers any components that you have.
import App from './App'
import router from './router'
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
Here I import the App.vue files and the router which we will get to. The components object holds the imported App and the router is also added.
App.vue
A Vue component files consists of three parts. A template, a script and a style section.
<template>
// your html here
<div id="app">
<h1>BlackBoard Vue Tutorial</h1>
<router-view/>
</div>
</template>
<script>
// your javascript here
export default {
name: 'App'
}
</script>
<style>
// your styles here
</style>
In the App.vue I have my global CSS styles and the main HTML template. Note the <router-view/> tag. It is under the header. This allows for us to using routing. It is a single page app but I created a second page and used routing just to show how routing workings in Vue.
The Router
You don’t need to use a router in Vue but I installed one when I created the template via cli. Routing is for going to different pages. The router file instance is located in the router folder and the file is name index.js.
// router/index.js file
import Router from 'vue-router'
import BlackBoard from '@/components/BlackBoard'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'BlackBoard',
component: BlackBoard
}
]
})
Here I import the router object and the blackboard Vue from the components folder. I then request that the middleware router is to be used , next I export a new Router object that as an array called routes. The routes array takes objects that require a path, a name and a component. With this done I can now access my blackboard.vue from the “/” path.
To add a new route I simply added a new object to the routes array.
// router/index.js file
import ContactView from '@/components/ContactView'
// add this object to routes array
{
path: '/contact',
name: 'ContactView',
component: ContactView
}
Above I added a contact route. Going to this route will display the ContactView component. Be sure to import your component before using it.

Components
You can place your components wherever you want once you import them accordingly. However the template I used had a components folder so all my components when there. The main component is the BlackBoard.vue but I have other views as well. Well actually App.vue is the main component. The other components are passed through it using the router component.
Declarative Rendering
Vue does this thing where you can declarative render data to the DOM using straightforward template syntax. So for the blackboard Vue component I have the message variable which is declared in the data function of my component.
// BlackBoard.vue - template tag
<template>
<div>
{{ message }}
</div>
</template>
// Blackboard.vue - script tag
<script>
export default {
name: 'BlackBoard',
data: function () {
return {
message: "hello world",
}
},
}
</script>
So when the view loads the div element will display the message “hello world”. For components you have to return the data has a function as show above. However if it was just the app instance you can do the following.
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
If I change the variable message it would reflect in the view. So I could update my page that easily without refreshing the page. How I would change it you will see shortly.
Binding Attributes
v-bind
Using v-bind we add dynamic styles to the div. To learn more about v-bind check out the docs here.
// blackboard.vue - template sec
<div class="board" v-bind:style="{backgroundColor: bgColor, fontSize:realTextSize, color:ftColor}">
{{ message }}
</div>
The above code shows the v-bind on styles attribute. It takes an object with some keys and values. Vue changes the hyphenated CSS styles to camel case so background-color become backgroundColor. The values are variables namely bgColor and ftColor. Note that realTextSize is special we will come back to that. With the v-bind on styles when can now dynamically change the background color and the text color, all we have to do is change the variables bgColor and ftColor.
// blackboard.vue - script sec
export default {
name: 'BlackBoard',
components : {AboutView},
data: function () {
return {
pageCount:1,
message: "hello world", // default message
isActive : true,
bgColor : "#fff", // change to change background
ftColor : "#000", // change to change text color
textSize : 15,
pages : {}
}
},
v-on
The short hand symbol is the at ( @ ) sign. I use the modifier a lot for my buttons section. The buttons section is show below.
<div class="board-tools">
<button id="btn1" @click="changeColour()">Black/White</button>
<button id="btn2" @click="changeSizeUp()">+ Size</button>
<button id="btn3" @click="changeSizeDown()">- Size</button>
<button @click="addPage()">Save Page</button>
<button @click="newPage()">New Page</button>
<button @click="goToUrl('about')">Learn More</button>
</div>
From the above I have a few functions attached using the on click v-on command. I used the short hand version but if I wanted to attach a on click listener using the normal way it would look something like this.

<button v-on:click="addPage()">Save Page</button>
But the @ sign is much cleaner. So where do all these methods exists. That’s a good question.
v-model
You can use the
https://vuejs.org/v2/guide/forms.htmlv-model
directive to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type. Although a bit magical,v-model
is essentially syntax sugar for updating data on user input events, plus special care for some edge cases.
The input that I add the v-model directive to was the message box that I typed the information to go on the blackboard.

I added the v-model here so that I could modify the message attribute dynamically. Whatever the users enters in the text field the message attribute will be updated.
<input v-model="message" type="text" placeholder="Enter text">
Remember the main view of the blackboard has the message attribute inside of it. So the text changes in the main view.
<div class="board">
{{ message }}
</div>

v-for
We can use the
https://vuejs.org/v2/guide/list.html#Mapping-an-Array-to-Elements-with-v-forv-for
directive to render a list of items based on an array. Thev-for
directive requires a special syntax in the form ofitem in items
, whereitems
is the source data array anditem
is an alias for the array element being iterated on:
I used this directive to display the pages section. Once you save a page it is added to the pages section. You can click on a page item and it will display the content of that page in the main view.

My layout for the pages section is show below. We have a variable pageCount that changes once a page is added.
<div class="board-pages">
<h3>Pages ({{pageCount -1}})</h3>
<ul class="pages-list">
<li v-for="item in pages" :key="item.id" >
<a class="page-item" @click="goToPage(item.id)">{{ item.message }}</a>
</li>
</ul>
</div>
We loop through the pages object and retrieves an item, we pass the item.id to the goToPage function to display the data on screen.
The pages variable is an object created in the data function in the script section of the Vue component. The addPage function shows how a page is added to the pages object.
// snippets from blackboard.vue file
pages : {} // object declared in data() {}
// add a page to the pages object
addPage () {
this.pages[this.pageCount] = {
"id" : this.pageCount,
"message":this.message
}
this.message = "";
this.pageCount += 1;
},
The list rendering prefers that each item as a unique id so we create a list of objects with a unique key id. The unique id is the pageCount variable and then we add the message as well. After we add a page to the pages object we clear the message variable and updates the pageCount variable.
When we click on a page item we show the page data.
<a class="page-item" @click="goToPage(item.id)">{{ item.message }}</a>
The goToPage function simply gets the message from the pages object and sets the message variable to it.
// method from methods object in blackboard.vue file
goToPage ( id ) {
var page = this.pages[id];
this.message = page.message;
},
Methods
When exporting your Vue component one of the objects that can be added is a methods object. This object takes a list of functions you created that can be accessed in the template Vue. When you add on click directives you can point the event to a function you created in the methods object of your component.
// blackboard.vue - script sec
export default {
name: 'BlackBoard',
data: function () {
return {
message: "hello world"
}
},
methods: {
changeColour () {
var colors = ["#fff","#000"];
if(this.bgColor === colors[0]){
this.bgColor = colors[1];
this.ftColor = colors[0];
}else{
this.bgColor = colors[0];
this.ftColor = colors[1];
}
console.log("changing to false");
},
Above I show the changeColor function. It toggles the screen display between black and white. If the background is white the text color is black and vice versa. In the template section this method is accessed easily
<button id="btn1" @click="changeColour()">Black/White</button>
Computed Properties
You can have inline computed properties since Vue brackets allow you to add some JavaScript functions in them. But for better usability you can return a computed object in your Vue component.
// blackboard.vue - script sec
computed: {
// a computed getter
realTextSize: function () {
// `this` points to the vm instance
return this.textSize + "px";
},
}
Here I used realTextSize as a computed property. In order to increase the text size I had to format the integer textSize and add the px. You can see how the computed property is used below. Once the textSize changes the realTextSize gets updated and the fontSize gets updated because of the v-bind property on style for the div. Its all pretty neat stuff. The textSize variable is declared in the data object.
// blackboard.vue - template sec
<div class="board" v-bind:style="{backgroundColor: bgColor, fontSize:realTextSize, color:ftColor}">
{{ message }}
</div>
Child Components
To test the child components features of Vue I added an about view in my blackboard.vue file. Once you import the component and add it to the components object in your Vue instance you can use the component has a tag in the template.
// blackboard.vue file
<AboutView/> // rendered from this tag
<script>
import AboutView from './AboutView.vue'; // import
export default {
name: 'BlackBoard',
components : {AboutView}, // add imported component
}
</script>
Its that simple. Now whatever I put in the AboutView.vue file I can see in the blackboard.vue file. You can pass data between components as well but I didn’t research that any further.
So far we have being using single file components but from the Vue documents I just wanted to try one of the component instances. Their documentation has this component below.
// main.js file
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Once a component is created like this you can access in you app views. So in the blackboard.vue file all I had to do was add the component as a tag and it worked perfectly.
<button-counter></button-counter>
Conclusion
This is by far a pretty small demo for using Vue. But it shows its power and what you can accomplish with it. It has really power in interactivity. When using it think about dynamic applications. One’s that will require user feedback, live instant user feedback. Don’t just use Vue to build your simple static applications. Consider its power and use it accordingly. Well actually Vue is great for mockups as well. Guess its all up to you.
Big Text Small Text Black Screen Child Component