What I have written below is based on a few assumptions I am making on your part. At this point, I am assuming you have played around with the Vue.js framework and are pretty comfortable working with components, or component composition. I’m not a fan of assuming things in general, and I aim to cover more introductory topics, but for now, this post takes into account those assumptions I mentioned before.
A lay of the land
When I’m coding, what I like to do is get a lay of the land—a bird’s eye view of what it is I’m trying to accomplish.
For a user to log in into something, I’ll need to capture some of their information. Let’s break down a component that handles a “log in” process. Let’s call our component
LoginView. The template for this component will be relatively straightforward. We use two input elements and a button. We can ignore the component’s styles for now:
Next, let’s do a little bit of planning
First, recall how Vue handles events and props:
Events go up, and props go down. That means, any child component should push its events up to its parent and any parent component should push its props down to the child component. If we apply this to our
LoginView component, then an event occurs once we click the button. From the users perspective, that event is them logging in. From Vue’s perspective, that event is being pushed up to the parent. To do this, let’s create a method that we can fire if a user clicks our button:
There are two things we have added to our code. First up, we created a method called
login() that executes if we click the button. Second, we have now attached a click event to our button by way of the
v-click directive. Essentially, we can think of this as:
In other words,
v-click will execute the
login() function for us.
Let’s take a closer look at our
We can see that we are calling some method called
this. What this means is that we are going to call
$emit() on our
LoginView component. You can think of it as something like
LoginView.$emit(). What exactly is
$emit? It is a Vue-specific method that grabs a string and an object—commonly called a payload in Vue—and bubbles it up to the parent component.
Let’s quickly imagine our parent component for
LoginView. Let’s call it
AppContainer is always listening for an emit event from any of its children. That’s the same for any parent in Vue. They’re all listening for
$emit events from their children. Once
login() is executed, it creates an event by way of the special
$emit function and passes a single string as its argument. In
AppContainer, it now knows that
'userCredentials' has been emitted by its
LoginView child. This is great! So, what now? Well, let’s take a look at our
AppContainer template for a second:
I’ve gone ahead and filled out a few things in the above example. First, we use the
v-on directive. Remember the
v-click method example I gave above? Here it is again:
v-on works in a similar way. You’ll see this a lot in Vue. Think of
v-on:userCredentials="checkCredentials" as the following:
AppContainer hears the emit event from its child,
LoginView, it recognizes that the event has a unique name called
userCredentials and executes the
checkCredentials() method in the parent. At this point,
checkCredentials() is where we can send a request off to our backend. However, we have nothing to check our backend with, right? We need to grab our user’s username and password. To do that, we need to modify what we send to
LoginView’s parent. Recall from before:
[$emit is] a Vue-specific method that grabs a string and an object—commonly called a payload in Vue—and bubbles it up to the parent component.
Let’s modify our
login() method so that
$emit() bubbles up a payload containing our user’s username and password:
Awesome! Now we are sending up an object with two properties and their respective values. Unfortunately, we are sending up empty strings at the moment. We need to substitute these values with what the user entered, though, right? Let’s do that next.
The data model
There are many ways to do this. I find that recording the username and password in the data model is a beautiful and clean way to do this. It is also incredibly easy to debug.
Now that we have our two properties in our data model, we can use another Vue directive called
v-model is a two-way data binding directive. That means we can directly write to our data model via our input fields. Let’s go ahead and add this directive to each of our inputs:
At this point, whatever a user types into username and password gets immediately added to our component’s data model. After our user has entered their credentials,
LoginView’s data model might look something like this:
Phew! At this point, we have done a lot so far. We are in the home stretch! Once you are ready, let’s finish this sucker up!
The home stretch
Now that we have our data model in place, we ought to update our payload, right? It is still bubbling up an object with empty string values for its
login() is called, it’ll let
LoginView’s parent know, and send along the
userCredentials payload. Outside of the scope of this post is how we can push this captured data to our backend. At Strong, we are using Parse, so we fire these details off to Parse to check against our users to see if the credentials exist.
We have done some impressive things at this point. We capture data and send it to
LoginView’s parent. All that is left to do to finish this component off is to prevent our form from submitting.
Prevent our form from submitting
Due to the nature of the HTML
form element, once we hit our button, it submits the form and causes the page to refresh. Luckily for us, Vue has us covered. Vue provides us with event modifiers for the
v-on directive. Let’s modify our button so that it prevents the form’s default behavior:
Now we can hit that button all we like, and it doesn’t cause any page refresh. Win!
There we have it! We have a fully-functioning component that follows the golden rule of single responsibility. It captures a user’s credentials and serves them up to its parent. It’s a great foundation to build upon with features such as form validation and error messaging.
Thanks for reading!
I highly appreciate you stopping by today and reading this article. If you enjoyed this one, might you be up for sharing it and helping me get the word out? 😘