Components overview

Author: Dawid Adach

-

As we noticed in a previous lesson our App.vue component consisted of three parts:

  1. Template
  2. Script
  3. Style

In this lesson, we will take a closer look at each of these.

First, please replace the content of App.vue file with the following content


<template>
  <div class="app">
    <h1>This is your first component in Vue</h1>
    <h3>{{ message }}</h3>
  </div>
</template>

<script>
export default {
  name: "App",
  data: () => ({
    message: "Powered by MDB!"
  })
};
</script>

<style>
.app {
  margin: 0 auto;
  font-family: sans-serif;
  background-color: #ccf7e2;
  padding: 10px;
  border-radius: 5px;
  max-width: 500px;
}
</style>
      

Save the file and preview. You should get something like this

Component preview

1. Template

1.1 Single root element

This part of the component is responsible for rendering its view. As you notice we use HTML inside. One important thing to remember is that the content inside should contain only a single root element. In other words - it should always be wrapped with some placeholder (i.e. div).

If we try to render two tags next to each other, the compiler will complain.

2 root elements cause an error

1.2 Mustache string interpolation

The other interesting and possibly new to you element is the {{ message }} heading.

This is so-called "Mustache" syntax (double curly braces). This text interpolation is the most basic form of data binding. As you may notice, the message variable is dynamically replaced by the string assigned to the message variable inside the data function within script part.

Text interpolation

Using JavaScript Expressions

So far we’ve only been binding to simple property keys in our templates. But Vue.js actually supports the full power of JavaScript expressions inside all data bindings. For example the code below:


    <ul>
      <li>{{ number + 1 }}</li>
      <li>Value of ok var is: + {{ ok ? 'true' : 'false' }}</li>
      <li>{{ message.split('').reverse().join('') }}</li>
    </ul>

    [...]

  data: () => ({
    message: "Powered by MDB!",
    number: 5,
    ok: true
  })
    

Runnint the above will result in:

JS expression

2. Script

This part of the code is important for each component for a few reasons. It's a place where:

  1. we can export our component (and define its name) so that we can use it in other components
  2. we have to list external components before we are be able to use them within our component
  3. we define attributes (variables) their values
  4. we define JavaScript functions used within a component

We will study the first and second point in details in the next lesson where we will learn how to export and import components within Vue. For now, let's have a closer look at points three and four.

2.1 Attributes

As you already seen in a previous lesson, we can define variables inside the data function so we can use them inside our template part:

We can use them as part of our logic, for example:


<span v-if="visible">Now you see me</span>
    

  data: () => ({
    message: "Powered by MDB!",
    visible: true
  })
    
Visible

Or as placeholders for our data (which can be directly modified using functions):


    <ol>
      <li v-for="todo in todos">{{ todo.text }}</li>
    </ol>
    

  data: () => ({
    todos: [
      { text: "Learn JavaScript" },
      { text: "Learn Vue" },
      { text: "Build something awesome" }
    ]
  })
    
Todos

2.2 Functions

As you already know, we can do quite a lot of JS inside template sections using Mustache interpolation. Though, in-template expressions are very convenient, they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example:


<li>{{ message.split('').reverse().join('') }}</li>
    

At this point, the template is no longer simple and declarative. You have to look at it for a second before realizing that it displays the message in reverse. The problem is made worse when you want to include the reversed message in your template more than once.

That’s why for any complex logic, you should use functions and return final result.


<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
    

export default {
  name: "App",
  data: () => ({
    message: "Powered by MDB!",
  }),
  computed: {
    // a computed getter
    reversedMessage: function() {
      // `this` points to the vm instance
      return this.message
        .split("")
        .reverse()
        .join("");
    }
  }
};
    
Computed

As you can see we can use double culry braces (mustache interpolation) not only to return value of a variable but also to call functions defined withing script part.

3. Styles

Last but not least is our CSS part. This section is quite self-descriptive. It's meant to store all the styles used by the component. What is important is that styles can be scoped.

This means that if you use a style like that below:


<style>
div[class*=" col"] {
  border: 1px dotted black;
}
</style>
  

...this style will be applied to any div within the entire website. It will be global. If you want to narrow its scope to divs within our component only, you can add the scoped option:


<style scoped>
...
</style>
  

Rate this lesson

Previous lesson Download Next lesson

Spread the word:
Do you need help? Use our support forum

About the author

Dawid Adach
For more than 5 years Dawid worked as an IT Consultant specializing in SOA/EAI/ESB in the banking domain. He gained experience working in countries like Netherlands, Belgium, Poland and India developing enterprise-class systems for the most prestigious companies. Since co-founding mdbootstrap.com & brandflow.net in 2016 he has been using and teaching technologies such as Angular, TypeScript, PHP, AJAX, Mongo, SQL, Hadoop Stack, Virtualization, Automation and many others...