Developing Web & Mobile applications and highly interactive and visually appealing front ends is a highly complex task. Your code can get messy really quickly especially when the Page or View you're working on will enable the user to do a number of tasks.
There is a fine balancing act developers need to preform when developing User Interfaces, because they are often the only aspect that you application will be measured by the users. So it is essential that the user interface is simple to understand and use while ensuring the users can do what they need to do
UI is like a joke. If you have to explain it, it isn't that good!
unknown
There is an additional aspect need to bear in mind, is that the same adage applies to other developers who will support your code. The code needs to be easy to understand and free from complexity.
Complexity comes about because of hundreds or thousands of small dependencies and obscurities build up over time.
Complexity is caused by two things : dependencies and obscurity
John Ousterhout : A Philosophy of software design
To tackle this, it is essential to attempt to make your code as isolated and compact as possible to ensure other developers can easily understand your code to assist them when maintaining, enhancing or supporting your code in the future.
A Philosophy of Software Design
how to decompose complex software systems into modules that can be implemented relatively independently.
VueJS Components
Vue Components are a handy, powerful and important utility that enables developers to create custom elements which can be reused in HTML.
Vue Components are single, independent units of an interface that have their own state, markup and style. Their key aspect is that they help to encapsulate reusable code.
In this post we are going to examine some key aspects of using components in your application to help isolate specific functionality in your code and how to enable basic communication between components.
Specifically how to start using Components to start refactoring your code base. The code base we're using is from an actual application I am building as a personal side project and the code can be found in the Components branch. In the code base, there are some intentional mistakes which are often implemented to introduce or to set the scene for follow up tutorials.
In previous examples in the code base we implemented a number of separate views or pages for different areas of functionality in the application. The Views were essentially just Components which have been placed in the Views folder.
In this tutorial, we are going to start to refactor this slight design error to create reusable components we will be able reuse across application.
Create Profile Component
The first issue we are going to tackle is a relatively simple component to create, but it is still going to incur a fair amount of complexity which will help us to understand some of the workings of Vue Components.
We are going to create a simple component to enable the user to View and Edit personal information on their profile.
We created our initial project making use of the Vue CLi - How to start a new project using Vue.js - by default this will create a components folder for the intention of developers creating their reusable application components.
We are going to create an additional folder in this folder and name it profile, which we are going to store all our profile related components. In the folder we will also create two new components, so we using the handy Webstorm template functionality using File --> New --> Vue Component to create our components Profile and Language
This we create the default empty Single File Component structure, which we will utilise to help build our Component
The first thing we're going to do is import the MDB Vue Pro- Material Design Components we will utilise to speed up our UI design. These are also at the most basic level just Components that have been designed to be reused.
We will then add our markup to layout our initial content.
Despite a lot of code going on, which the essence of what is going on is relatively simple. We have created to inputs which are going to used to display profile information. We simple use Two-Way binding using v-model
to the two fields we're really interested in.
The we make use of the MDB Vue Pro - Popover Component to display a box with content after a click on an element, similar to the tooltip contains more content.
The core of what we are interested for the purpose of this section are the lines
Passing Data with Props
A component won't be that useful unless you can pass data to and from it. This is where Props
come into play.
Props
are custom attributes you can register on a component. To enable the passing of values via prop attribute, it becomes a property on that component instance.
We will create a profile prop, which in our example is going to be an Object
We could add multiple string type props to our code, but for our particular use case an object will suffice at this point.
Our simple object, is ready for use at this point. All that is left for us to do, is to refactor our Overview view to make use of our new component.
The first thing we'll due is import the component by adding a line into our Script section
We can now also register our component for use in our View.
Now can simply refactor our initial layout to make use of our new component. We can simply use <profile > to reference our component. We can also pass data to our profile property making use of the :profile
We can now simply pass data to our component by registering a Profile object in the data of or view and ensuring we get the data from our database. In this example we are making use of the Google Firestore Real Time database. How to Install Firebase with Vue.JS will explain more about this useful technology to build real time applicaitons
If we run our application we'll see that everything just works now and we have successfully completed our new reusable component.
In our simple implementation at this stage, we simply enabled v-model
two way binding, any changes we make to the content will automatically be updated to our Parent Component profile object. So in our case we have to do nothing else to enable saving of the data everything else remains the same.
Parent to child communication
The example about was an example of Parent to child communication in vue. In this type of communication, the parent passes data to the child by adding an argument in the component declaration.
In the child component we provided an input property, which in theory provides one-way communication from parent to child. However, because we enable v-model on the properties we used we were able to simulate two way binding.
This is not necessarily best practice approach and could be considered a dirty hack.
Building the language component
At this stage, this is as far as we're going to go with the Profile component, there is still a lot of functionality we want to enable on this component but for now it will suffice for our purpose.
We will now develop an additional component which will enable the User to select which programming languages they are proficient in. In this initial example we are going to enable communication between components which is a common requirement when developing components.
In the following example we will use Child to parent communication to enable communication between components.
Child to parent communication
Events ensure communication from child to parent. We will fire an event from the child component to emit
a message while registering a listener in parent component using v-on:
directive.
When using Events, arguments are an optional and you can pass n number of arguments.
We are going to develop a slightly more complex example of a component, primarily because in our example our component is going to retrieve data from our Reference Data API we developed with Strapi and GraphQL.
We previously created our Language component, so we can go ahead and add our markup to define the functionality we want to create.
We are providing the user with a Select control to enable the user to select from a list of programming languages, then click a Button to add the language and be displayed in a list using Chip control to view it.
In this example the MDB Vue Pro Chip component emits a closeChip event which provides a value which contains the value of which chip has been closed, so we can update our data store.
In this example we are going to define a function in our code which won't do much but pass this data back to our Parent control.
We are going to populate our list from values retrieved from our Reference Data API, I previously discussed this in Creating Reference Data API with Strapi and using GraphQL
We will create a property on our Component - skill - which will be an Array.
The key important aspects we're going to introduce is that we will create two Methods add and remove which are going to emit an event to notify the Parent control that something has happened.
When we now register our control on our page. We will defer execution of what happens when these events are raised to functions on our parent control
The two functions on our Parent control, will simply Add or Remove items from the Parent array and save the changes to the database.
Summary
In this post we covered some basic aspects in creating reusable components in Vue.JS
- What is this Directory.Packages.props file all about? - January 25, 2024
- How to add Tailwind CSS to Blazor website - November 20, 2023
- How to deploy a Blazor site to Netlify - November 17, 2023