We can think of components as the building blocks of a UI. Each one is a self-contained piece of functionality, usually combined with a host of other components in a tree-like structure to form the UI of the entire web application. These components are also often reusable, and can be simply dropped into any part of the application where required.
A component in Vue is made up of two fundamental parts: presentation and behavior. The presentation part is simply the HTML template that is used to represent the data we are trying to display in the UI. The behavior part is a JavaScript object containing only the data relevant to that specific component, and any JavaScript functions necessary to manipulate that data and interact with the browser. This interaction includes handling the events raised by the browser, as well as refreshing certain portions of the UI depending on how the data has actually changed. Vue is smart enough to only refresh the parts of the UI that need to be, and doesn't bother refreshing the parts where the data hasn't changed.
In many SPA frameworks, this results in a single component being split into at least two, potentially three, separate physical files; a HTML file for the template; a JavaScript file for the data and behavioral functions; and an optional CSS file for styling the presentation of the component. In Vue, we have the concept of a single file component. We can use a custom file extension that allows us to combine these three aspects into a single file that contains three root elements: template, script, and style. In the following code snippet, we can see an example of a single file component:
<template>
<div class="product">
{{ name }}
</div>
</template>
<script>
export default {
name: 'product',
data () {
return {
name: 'Hands on ASP.NET Core and Vue.js'
}
}
}
</script>
<style>
.product {
font-size: 12px;
font-weight: bold;
color: teal;
}
</style>
The presentation part of this component, that is, the template and style sections, are incredibly simple. All we do is render a standard div element with a product class, and set the font size, weight, and color of that specific class using CSS. Inside the div element, we're using Vue's standard handlebar syntax to dynamically render a name variable. This variable is declared within the behavior part of the component, which again means the script section. Standard component data properties are declared inside a plain JavaScript object, which must be returned from a function named data. In this case, we return a simple object with a single name property, initialized with the Hands on ASP.NET Core and Vue.js value. This will subsequently be the text rendered inside the div element of template.
Each component should adhere to the SOLID principles of software design, and as such should only have a single responsibility. As soon as any single component starts to become overly complicated and difficult to see at a glance what its purpose is, it's probably time to refactor and extract a new component. Components are more often than not used in parent-child relationships, and Vue provides mechanisms for allowing related components to communicate with one another. Parents can pass data down into their children, and children can notify their parents of changes to their data. These parent-child relationships are the branches of our component tree, and there are many different ways that we could choose to break a UI down into this structure.