9.8.3 Single File Components - caligrafy/caligrafy-quill GitHub Wiki

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 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.

Component File

  • .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

Component File Structure

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>

Component Types

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 the router-view. The router-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 the src/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 the src/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.

Component Communication

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.

Parents pass data to Children through Props

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 the message 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>

Children emit events to pass information to Parents

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>



Next Section: State Management

⚠️ **GitHub.com Fallback** ⚠️