Mario 5
Today you won't be adding any new features to the project. Instead you will refactor the existing codebase to use Vue.js instead of "vanilla" Javascript for manipulating the DOM.
Obtaining the Starter Code
-
Navigate into your
mario-jsdirectory. -
Make sure you do not have any uncommitted changes:
$ git status On branch mario4 Your branch is ahead of 'origin/mario4' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working directory cleanIt should say "working directory clean".
If you do have uncommitted changes, then
addandcommitthem now. -
Switch to the
mario5branch:$ git checkout mario5 Switched to branch 'mario5' Your branch is up-to-date with 'origin/mario5'. -
Pull down the latest changes.
$ git pull Already up-to-date.Sometimes, the staff might make last-minute changes to the starter-code. Running
git pullhere ensures that you will have the very latest version of themario3branch.Usually you will just see:
Already up-to-date.But in the event that we did make some changes after your initial
git cloneon the first day of class, runninggit pullnow pulls down those changes, and you will see a different message outlining the changes.
Take a Look
Preview
If you open up the page in a browser, you will see that it looks the same as last time, but it doesn't function anymore. You can type in the textbox, but nothing happens when you submit the form. That's because we have started the refactoring process, and left some gaps for you to fill in.
Code Changes
Let's look over the code. Notice the following changes:
-
At the bottom of
mario.html, we have an additional<script>tag right before the one that loadsmario.js. This script imports the Vue.js library so that we can use Vue's methods in our own code. -
We have refactored the code to (partially) use Vue syntax:
-
pyramidRows, instead of directly modifying the DOM, now returns a list of strings: one for each row. -
The "Draw a pyramid" button uses Vue's
@click="clearAndRedraw"instead ofaddEventListener. - Vue will give the height input a class if
this.erroris set (that's what the:class="error ? 'invalid-field': null"bit is doing).
-
Your Task
Heads up: there's a lot of new things in today's class. If you get stuck, see if you can write down a reason that you're stuck as a google search term. Some examples:
- vue js display value
- vue js input value
- vue js computed property
- vue js for loop
You might also try looking through the documentation for Vue.js, which is quite complete.
Now go ahead and complete the following tasks:
-
Fill out the
checkForErrorsfunction. It should return an error message if the givenheightStrvalue is the empty string, not a number, less than 1, or more than 100. If there are no errors, returnnull. This piece is difficult to test by itself, because we haven't wired up the inputs or events yet. So, fire up the developer console, and try calling the function interactively. Does it do the right thing forcheckForErrors('0'),checkForErrors('10'),checkForErrors(''),checkForErrors('fifteen')? Are there any other examples you can think of that would make good test cases? -
Since the error message from
checkForErrorsis being set inclearAndRedrawasthis.error, it's available in our template. Use the double curly braces ({{ }}) to show the error message. Hint: you won't need to refer tothis, the template assumes that's where your data is stored. -
Currently the pyramids always have a height of 5, no matter what the user types. Let's fix that. Inside the template, add a
v-modeldirective so that the input is kept in sync withheightStr. -
Computed properties are functions on your view's data that are kept up-to-date. They're called whenever the data changes, but otherwise cached. Create a new computed property called
errorthat it returns the result ofcheckForErrors(this.heightStr). Also, delete theerrorentry indata:and the update inclearAndRedraw. -
Fill out the other computed property,
rows. It should return the result of callingpyramidRowsonthis.height. Use your new computed property towards the bottom ofclearAndRedraw. - Now we get to the good stuff! We're going to get to remove that ugly direct DOM manipulation code (almost all of
clearAndRedraw). Instead, we'll use a nice declarative template. Inside the#pyramiddiv in the template, add the following:
<p v-for="row in rows" v-html="row" />
This says "make a <p> for each entry in rows. Each p's .innerHTML should be set to the value of row.
- Delete all the DOM manipulation code from
clearAndRedraw. It should just look like this:
// Stop the form from causing a page refresh.
evt.preventDefault();
if (this.error) {
// Stop drawing, we've got errors.
return;
}
this.height = parseInt(this.heightStr);
Committing Your Changes
-
Add your new changes:
$ git add mario.js -
Then commit, along with a descriptive message.
$ git commit -m "refactor to use Vue.js"