-
-
Notifications
You must be signed in to change notification settings - Fork 2
9.8.3 Single File Components
Vue provides a powerful way of defining reusable templates through components
. When working with smaller projects, all the components needed can be defined in the index.php
markup and in the main.js
script. However, in larger scale applications, having all the components template defined in the markup and their behavior defined in the script can become cumbersome.
With the Caligrafy Vue integration, we could leverage the power of the Vue CLI to separate each component into its own file, thus the name Single File Component (SFC).
In this section, we will look at the different types of components, how they are structured and organized, how they are registered and most importantly how they communicate with each other.
-
.vue
: the Vue Single File Components have a.vue
extension - organization: components can include other components thus creating a parent/child relationship
- import: components can be imported and used in other components
Every Vue component has:
-
template
: the template is the HTML markup of the component -
script
: the script is the javascript definition of the component -
style
: the style is the css or the css source for the component
<!-- Component Example -->
<template>
<div id='parentcomponent'>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from '@/components/global/ChildComponent.vue';
export default {
name: 'parentcomponent',
components: {
'child-component': ChildComponent
},
data() {
return {}
},
methods: {
// define methods
},
computed: {
// computed variables
},
mounted() {
// execute methods and actions upon mounting
},
watch: {
// watched properties
}
};
</script>
<style>
<!-- style goes here -->
</style>
The Vue components can be organized at will. They could have more components within them or they could belong to many components. That flexibility makes it possible to create hierarchies of components that can be included in each other. It is therefore possible to create structures
, pages
, global
and local
components.
-
structure
: a structure component is a type of component that is meant to define the overall layout of the page such as header, footer, navigation etc. The most important component in a structure component is therouter-view
. Therouter-view
is the component responsible for toggling the appropriate content based on the defined routes. It is the structure component that ensures routing for a Single Page Application.src/App.vue
is an example of a structure component -
pages
: a page component is a type of component that is meant to represent content that traditionally lives on webpage. Page components are the components that are referenced in the routes. In Caligrafy, page components are all grouped together in thesrc/components/pages
folder.src/components/pages/HomePage.vue
is an example of a page component -
global
: a global component is a type of component that is reusable across all other components. In Caligrafy, global components are all grouped together in thesrc/components/global
folder.src/components/global/ShowNavigation.vue
is an example of a global component -
local
: a local component is a type of component that is not necessarily shared across components but that can have different flavors based on the context of where it is used. Local components can be placed at will in the Caligrafy structure.
Organized components might need to transfer information among each other. Depending on the relationship between components (parent or child), the way the information is transferred vary.
When a component is included in another component, it is the child component. In many instances, the parent component (the component containing the child) needs to pass data to the child component. The data is passed down through props
.
-
props
are defined in the script of a child component. For example, a component that displays a message that is passed from the parent needs themessage
to be specified as a prop in its script. Here is an example of how the code could look like.
<!-- Child Component Template -->
<template>
<div class='horizontal-center'>
{{ message }}
</div>
</template>
<script>
export default {
name: 'show-message',
props: ['message']
};
</script>
-
props
are assigned a value to be passed on to the child in the parent component upon use. Here is an example of how the code could look like.
<!-- Page Template Example -->
<template>
<div id='home'>
<div class='spacer-2'></div>
<show-message message="Welcome to Caligrafy"></show-message>
<div class='spacer-2'></div>
</div>
</template>
<script>
import ShowMessage from '@/components/global/ShowMessage.vue';
export default {
name: 'home',
components: {
'show-message': ShowMessage
},
data() {
return {}
},
methods: {
// define methods
},
computed: {
// computed variables
},
mounted() {
// execute methods and actions upon mounting
},
watch: {
// watched properties
}
};
</script>
-
props
values can be assigned in a hard-coded way as we have seen in the previous point. They could also be passed dynamically by binding the prop to a variable in the script.
<template>
<div id='home'>
<div class='spacer-2'></div>
<show-message :message='outputMessage'></show-message>
<div class='spacer-2'></div>
</div>
</template>
import ShowMessage from '@/components/global/ShowMessage.vue';
export default {
name: 'home',
components: {
'show-message': ShowMessage
},
data() {
return {
outputMessage: 'Welcome to Caligrafy'
}
}
};
</script>
A child component communicates with its parent by triggering an event.
- The event is captured by the parent in the template
<template>
<div id='home'>
<div class='spacer-2'></div>
<show-message @display-message='showMessage($event)'></show-message>
<div class='spacer-2'></div>
</div>
</template>
- The event is emitted from the child component
<template>
<div class='horizontal-center'>
<button @click="$emit('display-message','Welcome to Caligrafy')">Welcome</button>
</div>
</template>