Till now we have been working with Registering our Vue Components by using Vue.component
method. But with Vue CLI the way you can write and register the components is a bit different.
Open the App.vue
root component file from the application we generated via Vue CLI. Here is how it looks 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>
This is a root Vue component, But it sure does look different from the way we used to define and use our Components. It's a Single File Component.
If you think about a Component on your page, all it can be is the combination of three things, HTML which denotes its markup, javascript which denotes its behavior, and CSS styles which denotes its look. That's all there is to the Single file Components.
Vue Single File Components consist of 3 parts:
- template
- script
- style
With SFC you can define all the three aspects of your Components in a single file and with that, it makes a lot of sense to what exactly your component looks like and what you are trying to achieve with it.
Webpack
Writing single file components is possible because of webpack. The Vue CLI makes this very easy and supported out of the box. .vue
files cannot be used without a webpack setup.
You write single-file components in a *. Vue file, which browsers won't understand, and some of the syntax that you write to define a single file component also won't be picked up by certain browsers. We basically want to compile everything down to a bundled file that any browser can understand, and this is where Webpack comes into play.
No Need to Config Webpack
With Vue CLI 3, When you create a new project with the CLI, you don’t have to configure anything. You get out-of-the-box support for Babel, TypeScript, ESLint, PostCSS, PWA, Unit Testing, and End-to-end Testing.
Also, you will notice that by default there is no webpack config file.
Example of Single File Component
Though the structure of a single-file component may look different, everything we’ve learned so far with regards to components remains the same. We’re able to use all the properties a Vue instance component contains like data, methods, computed properties, lifecycle hooks, etc.
Let's create a simple example where we make use of props and methods in Single File Component
If you are following along and have created a Vue CLI project. Let's remove the boilerplate code from the Root Component so that the App.vue component looks like this.
<template>
<HelloWorld msgTo="India"/>
</template>
<script>
export default {
name: 'app',
}
</script>
<style>
</style>
We now have absolutely nothing in our Root Component, the template is empty, in the javascript contains just the name of the component, and the style tag is empty as well.
Do the same with HelloWorld.vue
component, remove everything. Since we are going to write our own component from scratch.
<template>
</template>
<script>
export default {
name: 'HelloWorld',
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Alright, let's begin working on our first Single File Components
#1 Import HelloWorld Component into Root Component
Since we have the App component mounted as the root. In order to use the Hello World component let's import it in and also use it in our template markup.
<template>
<HelloWorld msgTo="India"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld,
}
}
</script>
<style>
</style>
Notice that we are passing data named msgTo
from the root component down to the HelloWorld component. Since we don't have anything yet in our HelloWorld component you won't see anything on the screen just yet.
#2 Methods & Props in HelloWorld.vue component
As the second step, let's define props and methods in our HelloWorld component.
<template>
<div class="helloWorld">
<h1><span class="greeting">{{greeting}}</span><span class="greetingTo"> {{msgTo}}</span></h1>
<button @click="changeGreeting('Hello')">Say Hello</button>
<button @click="changeGreeting('Hi')">Say Hi</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data(){
return{
greeting: 'Hello'
}
},
props: {
msgTo: {
type: String,
default: 'World'
}
},
methods:{
changeGreeting(greeting){
this.greeting = greeting;
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.helloWorld .greeting{
color: blue;
}
.helloWorld .greetingTo{
color: red;
}
</style>
We have defined the prop msgTo, and along with that defined its type and default value. We have also defined two methods and registered them to the click events of the button.
Now when you open the screen you should see the following message on the screen.
There you go, you have your first single file component ready and working.