Basics of Vue

Nicky Liu
The Startup
Published in
11 min readMay 29, 2019

Along with React and Angular, Vue.js is one of the popular frameworks for JavaScript. In this article I will describe how to get a Vue app started and some of its basics.

npm install -g @vue/cli
vue create vue-test

Select default.

CD into it:

cd vue-test

Run the server with:

npm run serve

Paste the local url into your browser.

Open up “App.vue” inside of the “src” folder. You should see something like:

<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

We don’t need the style at the bottom or the image at the top, so let’s remove all of that.

It should now look something like:

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>

Perfect.

Everything you see on the current page is from the “HelloWorld.vue” file inside of the components folder. Open up “HelloWorld.vue” and delete the style at the bottom, as well as everything inside of the template aside from the div aside from h1. It should now look something like:

<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>

The page is now a blank page with only the h1, which contains the contents of the “msg prop” passed in from the “App.vue” file. The {{}} allows you to display the result of a prop you passed in, in this case the msg prop.

At the bottom of the “HelloWorld.vue” file you can find this:

<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>

This is required to allow “HelloWorld.vue” to receive the “msg” prop as a string from App.vue. The props will be different based on the names of the props passed in as well as their datatypes.

You can pass in more props as well, this can be done by simply putting another variable with a value inside of <HelloWorld.vue />, and adding the name of the prop and its data type inside of “props” inside of the export default script at the bottom of “HelloWorld.vue”.

Updating “App.vue” to:

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>

and “HelloWorld.vue” to:

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String
}
}
</script>

will now display a second headline which reads “This is message 2!”, the new “msg2” prop we passed in.

You can also add “data” to the exports back in “App.vue”, which returns key value pairs that which can be passed and accessed, and inserting into <HelloWorld :variableName=“keyName”>. This is similar to props from react.

<template>
<div id="app">
<HelloWorld :title="title" />
</div>
</template>
<script>
import VueTest from './components/VueTest.vue'
export default {
name: 'app',
components: {
VueTest
},
data() {
return {
title: "THIS IS A TITLE"
}
}
}
</script>

Go to HelloWorld.vue and add a line to display the title prop.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1>{{title}}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String
}
}
</script>

You could name the :variableName anything you wanted, although it must be set equal to the name of a key inside of quotes and the props must have the name of the variable being passed in as well as its datatype.

There are special attributes called directives that begin with “v-bind”. If you want to make text appear on hover, you can use v-bind:title=“keyName” in a span. V-bind is optional though, and it would work with just :title=“keyName” as well.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1 v-bind:title="hover">{{title}}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String,
hover: String
}
}
</script>

In App.vue add hover and a corresponding value inside of data.

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"
:title="title"
:hover="hover"
/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
},
data() {
return {
title: "THIS IS A TITLE",
hover: "Hover Hand"
}
}
}
</script>

Now if you hover over the heading that says title, “Hover Hand” will appear.

To use functions we go back to “App.vue” and use “methods” similar to how we used components.

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"
:title="title"
:hover="hover"
:changeTitle="changeTitle"
/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
},
data() {
return {
title: "THIS IS A TITLE",
hover: "Hover Hand"
}
},
methods: {
changeTitle() {
this.title = "Kappa"
}
},
}
</script>

Attributes inside of data can be accessed via this.keyName. The changeTitle method will change the title attribute inside of data to “Kappa”.

Add a button on “HelloWorld.vue” that calls the changeTitle function. We use a directive that calls a function on click. v-on:click=“functionName”. You can also just write @click=“functionName”

<template>
<div>
<span v-bind:title="hover">{{title}}</span>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
</div>
</template>
<script>
export default {
name: 'VueTest',
props: {
title: String,
hover: String,
changeTitle: Function
}
}
</script>

This will give you a button below the title with the fascinating name of “BUTTON!!!”. On clicking it your title should change to Kappa.

You can use conditionals with v-if=“keyName”. In “App.vue” add “hasTitle: true” to data, and add the method “toggleTitle() {this.hasTitle = !this.hasTitle}” to methods.

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"
:title="title"
:hover="hover"
:changeTitle="changeTitle"
:hasTitle="hasTitle"
:toggleTitle="toggleTitle"
/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
},
data() {
return {
title: "THIS IS A TITLE",
hover: "Hover Hand",
hasTitle: true,
}
},
methods: {
changeTitle() {
this.title = "Kappa"
},
toggleTitle() {
this.hasTitle = !this.hasTitle
}
},
}
</script>

Back to “HelloWorld.vue” and add a heading that will only show the title if the property “hasTitle” is true, and under that add a button that calls the “toggleTitle” function on click.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1 v-bind:title="hover">{{title}}</h1>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
<br />
<h1 v-if="hasTitle">{{title}}</h1>
<br/>
<button v-on:click="toggleTitle">TOGGLE BUTTON!!!</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String,
hover: String,
hasTitle: String,
changeTitle: Function,
toggleTitle: Function
}
}
</script>

There is now another title headline and a button that says “Toggle Button!!! below it. ”If we click the toggle button, the second title dissappears, and if we click it again, it reappears.

Now for forms. A form in vue looks like:

<form>
<p>
What is your name? <input>
</p>
</form>

Inside of input is where you set up the variable you want to change.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1 v-bind:title="hover">{{title}}</h1>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
<br />
<h1 v-if="hasTitle">{{title}}</h1>
<br/>
<button v-on:click="toggleTitle">TOGGLE BUTTON!!!</button>
<form>
<p>
What is your name? <input v-model="title" />
</p>
</form>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String,
hover: String,
hasTitle: String,
changeTitle: Function,
toggleTitle: Function
}
}
</script>

This will default the text inside the bar to the value of “title” from the data. Changing the value here will change the value of the “title” variable, and the other two titles from up above will change as well.

A checkbox input looks like:

<form>
<p>
<input v-model="hasTitle" type="checkbox />
</p>
</form>

Add that to the form in index.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1 v-bind:title="hover">{{title}}</h1>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
<br />
<h1 v-if="hasTitle">{{title}}</h1>
<br/>
<button v-on:click="toggleTitle">TOGGLE BUTTON!!!</button>
<form>
<p>
What is your name? <input v-model="title" />
<input v-model="hasTitle" type="checkbox" />
</p>
</form>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String,
hover: String,
hasTitle: String,
changeTitle: Function,
toggleTitle: Function
}
}
</script>

This creates a checkbox linked with the prop “hasTitle”. Clicking this change the value of hasTitle from true to false and visa-versa..

To make a list do:

<select v-model="keyName">
<option>
OPTION 1
</option>
<option>
OPTION 2
</option>
<option>
OPTION 3
</option>
</select>

In “App.vue” add “selected” under data:

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"
:title="title"
:hover="hover"
:changeTitle="changeTitle"
:hasTitle="hasTitle"
:toggleTitle="toggleTitle"
:selected="selected"
/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
},
data() {
return {
title: "THIS IS A TITLE",
hover: "Hover Hand",
hasTitle: true,
selected: ''
}
},
methods: {
changeTitle() {
this.title = "Kappa"
},
toggleTitle() {
this.hasTitle = !this.hasTitle
}
},
}
</script>

Add the select bar and a header below showing the result, which updates the value of select.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1 v-bind:title="hover">{{title}}</h1>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
<br />
<h1 v-if="hasTitle">{{title}}</h1>
<br/>
<button v-on:click="toggleTitle">TOGGLE BUTTON!!!</button>
<form>
<p>
What is your name? <input v-model="title" />
<input v-model="hasTitle" type="checkbox" />
</p>
</form>
<br/>
<select v-model="selected">
<option>
OPTION 1
</option>
<option>
OPTION 2
</option>
<option>
OPTION 3
</option>
</select>
<br/>
<span>Selected: {{selected}}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String,
hover: String,
hasTitle: String,
selected: String,
changeTitle: Function,
toggleTitle: Function
}
}
</script>

This will leave you a bar with 3 options to select from, and update the value below to display whichever you selected.

You can iterate over a loop with “v-for”.

On “App.vue” under data add a key whose value is an array container several items.

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"
:title="title"
:hover="hover"
:changeTitle="changeTitle"
:hasTitle="hasTitle"
:toggleTitle="toggleTitle"
:selected="selected"
:array="array"
/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
},
data() {
return {
title: "THIS IS A TITLE",
hover: "Hover Hand",
hasTitle: true,
selected: '',
array: [
{name: 'item1'},
{name: 'item2'},
{name: 'item3'}
]
}
},
methods: {
changeTitle() {
this.title = "Kappa"
},
toggleTitle() {
this.hasTitle = !this.hasTitle
}
},
}
</script>

You can display all the items as a list.

<ul>
<li vi-for="item in array">
{{item.name}}
</li>
</ul>

Add it to “HelloWorld.vue”.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<h1 v-bind:title="hover">{{title}}</h1>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
<br />
<h1 v-if="hasTitle">{{title}}</h1>
<br/>
<button v-on:click="toggleTitle">TOGGLE BUTTON!!!</button>
<form>
<p>
What is your name? <input v-model="title" />
<input v-model="hasTitle" type="checkbox" />
</p>
</form>
<br/>
<select v-model="selected">
<option>
OPTION 1
</option>
<option>
OPTION 2
</option>
<option>
OPTION 3
</option>
</select>
<br/>
<span>Selected: {{selected}}</span>
<ul>
<li v-for="item in array">
{{item.name}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
msg2: String,
title: String,
hover: String,
hasTitle: String,
selected: String,
array: Array,
changeTitle: Function,
toggleTitle: Function
}
}
</script>

Now all three items are displayed as an unordered list.

So far all of this work has been done on a single component. But it is also important to know how to use multiple components, as it allows us to re-use a component when we want to display something either again or something similar.

Create a new component file called “NewComponent.vue” inside of the components folder. Open it and enter the lines:

<template>
<h1>I AM A NEW COMPONENT!</h1>
</template>

Go to “App.vue” and examine the script. By default when we set this up it imported “HelloWorld.vue” with the “import HelloWorld from ‘./components/HelloWorld.vue’” line and “HelloWorld” inside of hte components section. Add an import line for “NewComponent.vue” and add “NewComponent” under “HelloWorld” inside of “components”. Also, just like we had <HelloWorld /> at the top inside of template, under that add <NewComponent />. Your “App.vue” should now look like:

<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"
msg2="This is message 2!"
:title="title"
:hover="hover"
:changeTitle="changeTitle"
:hasTitle="hasTitle"
:toggleTitle="toggleTitle"
:selected="selected"
:array="array"
/>
<NewComponent />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import NewComponent from './components/NewComponent.vue'
export default {
name: 'app',
components: {
HelloWorld,
NewComponent
},
data() {
return {
title: "THIS IS A TITLE",
hover: "Hover Hand",
hasTitle: true,
selected: '',
array: [
{name: 'item1'},
{name: 'item2'},
{name: 'item3'}
]
}
},
methods: {
changeTitle() {
this.title = "Kappa"
},
toggleTitle() {
this.hasTitle = !this.hasTitle
}
},
}
</script>

If you look at the page now, your new component has been added to the bottom, right under the “HelloWorld” component. The page now says “I AM A. NEW COMPONENT!” at the bottom.

Now you can display multiple components. But what if you wanted to display a component inside of another one? Like instead of having the “NewComponent” either always above or below the “HelloWorld” component, we wanted it inside the “HelloWorld” component, maybe in the middle?

All we need to do is import it inside of “HelloWorld.vue” itself, much like we imported it into “App.vue”. In script at the bottom, add the line “import NewComponent from ‘./NewComponent.vue’”. Notice that it is now being imported from “./NewComponent.vue” instead of “./components/NewComponent.vue”. This is because both of these components here are inside the same folder, where you are importing things frmo will change based on their locations relative to each other. Also add the “components: {NewComponent}, part between name and props inside the script tag. You can now use <NewComponent /> wherever you want inside of “HelloWorld”. Let’s try adding it right below the second headline that shows “msg2”.

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg2 }}</h1>
<NewComponent />
<h1 v-bind:title="hover">{{title}}</h1>
<br />
<button v-on:click="changeTitle">BUTTON!!!</button>
<br />
<h1 v-if="hasTitle">{{title}}</h1>
<br/>
<button v-on:click="toggleTitle">TOGGLE BUTTON!!!</button>
<form>
<p>
What is your name? <input v-model="title" />
<input v-model="hasTitle" type="checkbox" />
</p>
</form>
<br/>
<select v-model="selected">
<option>
OPTION 1
</option>
<option>
OPTION 2
</option>
<option>
OPTION 3
</option>
</select>
<br/>
<span>Selected: {{selected}}</span>
<ul>
<li v-for="item in array">
{{item.name}}
</li>
</ul>
</div>
</template>
<script>import NewComponent from './NewComponent.vue'export default {
name: 'HelloWorld',
components: {
NewComponent
},
props: {
msg: String,
msg2: String,
title: String,
hover: String,
hasTitle: String,
selected: String,
array: Array,
changeTitle: Function,
toggleTitle: Function
}
}
</script>

You can now see that the same line which was added to the bottom earlier is now added below the second headline, we have successfully imported the “NewComponent” into the “HelloWorld” component!

One final thing. We ignored the styling at the bottom of “App.vue” before, but we will need to go over how to style in Vue. It’s very simple, add <style> </style> at the bottom of “App.vue” and inside of that enter css like you would in a normal css sheet.

For example, go to “Helloworld.vue” and add an id to the first h1 and a class to the second h1. It should look something like:

<h1 id="id-1">{{ msg }}</h1>
<h1 class="class-1">{{ msg2 }}</h1>

Now add styling to them in “App.vue”

<style>
#app {
text-align: center;
color: blue;
}
#id-1 {
color: red
}
.class-1 {
color: green
}
</style>

Now all of the text will be blue aside from the first two lines, which we made red and green respectively. Easy right?

This guide went over how to create a Vue project, how to store and pass data and functions, various ways you can display and use props and methods to create an interactive page, how to import and use multiple components, and how to style. Thank you for reading, and hopefully this lets you start off your journey with Vue on the right foot!

--

--