Lesson 19 Vue.js Events

Mark Harder, 22 February 2019

Vue.js Events

In lesson 11 we learned about html events. Mouse click event, mousedown, mouseover, mouseout, dblclick, …

  • v- is how most vue.js directives start
  • v-on:click=”javascript”
    • v-on: -> this part says we want to add an event
    • :click -> this parameter tells vue.js what the event is
    • :input -> this parameter can instead tell it to fire on each keyboard input

Click Event

Lets try out our first event by logging the event details of a button click to the console.

  • index.html
      <button v-on:click="logEvent">button click event</button>
    
  • the logEvent method doesn’t exist yet, remember “logEvent” is JavaScript that will run.
    • Add logEvent to the Vue object methods.
        Vue({
        el: "#app",
        methods: {
            logEvent(event){
                console.log(event);
            }
      

      Picture of our page

Keyup Event

  • Add an input element that has an event for keyup, so we can capture each time the user types in a text box.
    • input element with keyup event, we don’t use the keypress event because it will occur before the keyboard press registers.
        <label for="#logEvent">Title:</label>
        <input id="logEvent" type="text" v-on:keyup="updateTitle">  
      
    • add method that updates our title data variable, which in turn will update the title on our page.
        updateTitle(event) {
            this.title = event.target.value;
        }
      

  • Video Link v-on:click & v-on:keyup
    • Length: 8:10 minutes
    • Size: 31 MB

Lets work with a more complicated HTML input element, date

First we will add an HTML element <input type="date"

  • https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date

  • index.html
      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8">
          <title>lesson 19</title>
          <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
          <script defer src="app.js"></script>
      </head>
      <body>
          <div class="div" id="app">
              <h1></h1>
              <label for="#b-day"></label>
              <input type="date" id="b-day" v-model:value="bday" ref="bday">
              <p></p>
              <input type="button" v-on:click="adddays(1)" value="+1 day">
              <input type="button" v-on:click="adddays(365)" value="+1 year">
              <input type="button" v-on:click="adddays(-1)" value="-1 day">
              <input type="button" v-on:click="adddays(-365)" value="-1 year">
          </div>
      </body>
      </html>
    
  • We have added 4 buttons, each with the job on increasing the date stored in our input type="date" element.
    • the input type date displays for the user a way to enter dates, but it has a quirk, it expects a string JavaScript data type not date. It also expects the date to be in the following format yyyy-mm-dd.
    • We are adding an attribute ref="" Vue.js ref documentation to our HTML element so that we can easily reference it later in our Vue JavaScript method.
  • app.js
      new Vue({
          el: '#app',
          data: {
              bday: '1999-11-01',
              bdaylabel: 'Birth Day:',
              title: 'Event Binding Example'
          },
          methods: {
              adddays(days) {
                  let e = this.$refs.bday;
                  e.stepUp(days);
              }
          }
      });
    
  • Because the input element has a ref="bday we can call it inside our JavaScript method using this.$ref
  • We select our input date element using this.$ref.bday, then we use a method on the input date element .stepUp() to increment the value of our date by a number of days.

  • Video Link register a reference to an element
    • Length: 4:10 minutes
    • Size: 21 MB

Conditionals

  • Remember we started using Vue templates to control the output to the screen / html elements. Well now we are going to expand our templates with conditionals.
  • Conditional is like in JavaScript if statement. For example, lets control the visibility of an html element based on a Vue data variable.
  • lets start by adding a new boolean data variable named showSubtitle
new Vue({
    el: '#app',
    data: {
        title: 'Vue.js Conditionals',
        showTitle: true
    }
});
  • We will use a Vue directive called v-if in our html.
<h1 v-if="showTitle"></h1>
  • The code that is in the “” quotes of the v-if= directive is evaluated as an expression that is considered to be either truthy or falsy. See the if (condition) test in JavaScript documentation .
  • Lets add an input checkbox that shows or hides our title.
      <label for="#showTitle">show title</label>
      <input id="showTitle" type="checkbox" v-model:value="showTitle">
    
  • The input checkbox does a 2 way bind to the data variable showTitle.
  • So when the input checkbox changes the value of the variable showTitle to false, then the html conditional v-if directive will not render the h1 element to the page.
  • Like regular JavaScript we can add a second conditional. v-else or v-else-if
    <h1 v-if="showTitle"></h1>
    <h2 v-else>Title2</h2>
  • If the condition for v-if is false, the the v-else will show. You can learn more in the Vue documentaion.

Loops

Looping through data and building our Vue elements.

  • Start by adding an array to our Vue data.
new Vue({
    el: '#app',
    data: {
        title: 'To Do List',
        ToDoItems: ['Finish lesson 19', 'Feed the dog', 'Make dinner', 'Play a game']
    }
});
  • Next lets add our html and use a new directive: v-for
  • Example: <li v-for="item in ToDoItems"></li>
  • This v-for directive will create a li element for each item in the array ToDoItems data variable.
  • We can see from our code above there is 4 strings starting with Finish lesson 19, so Vue will create 4 li elements (line items)
  • Heres our html
    <ol>
        <li v-for="item in ToDoItems"></li>
    </ol>
  • Our page should look like this.

    To Do List

    1. Finish lesson 19
    2. Feed the dog
    3. Make dinner
    4. Play a game
  • You can find more detail at the Vue documentation
  • Lets get more complicated and use an array og To Do objects, then we can bind a checkbox to a status boolean to show which items are done.
  • index.html
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>lesson 19</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script defer src="app.js"></script>
    </head>
    <body>
        <div class="div" id="app">
            <h1></h1>
            <ol>
                <li v-for="item in ToDoItems"><input type="checkbox" v-model:value="item.status"></li>
            </ol>
        </div>
    </body>
    </html>
  • app.js
    new Vue({
        el: '#app',
        data: {
            title: 'To Do List',
            ToDoItems: [{
                title: 'Finish lesson 19',
                status: true
            }, {
                title: 'Feed the dog',
                status: false
            }, {
                title: 'Make dinner',
                status: false
            }, {
                title: 'Play a game',
                status: false
            }],
        }
    });

  • Video Link v-for
    • Length: 6:08 minutes
    • Size: 20 MB

https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en


Assignment due for discussion next class and checked into GitHub by the Monday after that.

  • Create a new repo called lesson19
  • Copy the project you started in Lesson 16, convert it to Vue.
  • Use input controls and Vue.js directives: v-if, and v-on for events in your app.

Example Upgrade of an App to Vue

We are going to use https://github.com/mhintegrity/Tic-Tac-Toe-Pro for our example upgrade.

  1. Add Vue references to the html page
    Inside the head tag add a reference to Vue
     <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
    
  2. Wrap all the html inside the body tag in a div tag
     <div id="app">
         <h1>Tic Tac Toe Pro</h1>
         <div class="board">
         ...
     </div>  
    
  3. Upgrade the button tag event calls
    • Original index.html
      <button onclick="ResetGame();"
      
    • New index.html
      <button v-on:click="ResetGame"
      
    • In the original we called a JavaScript function named ResetGame(), we are now calling a methods function by the same name. See section 5 for the move of JavaScript function to methods in the new Vue code.
  4. Use Vue templates to update the screen XWins and Total Times.
    • Original index.html ```html

    X has won 0 total times.</h2>

    O has won 0 total times.</h2>

    Tied games 0 total times.</h2> ``` * New `index.html` ```html

    X has won total times.</h2>

    O has won total times.</h2>

    Tied games total times.</h2> ```

  5. Upgrade our JavaScript main.js file to a Vue instance.
    • Original main.js
       let gameState = {};
      
    • New main.js
      var vm = new Vue({
        el: '#app',
        data: {
            gameState: {}
        },
      
    • The el: '#app' references the new div id="app"
    • The gameState: {} replaces the local variable gameState
    • Next we will add a new instance lifecycle hook section, that we have not yet covered. Basically there are methods that will run at different times while the app/page runs. You can see a diagram of when these functions run on this page: https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
    • New continued main.js
         mounted: function() {
             // Vue instance's lifecyle that runs after an instance is mounted. 
             this.InitializeBoardState();
         },
      
    • We use the keyword this when referencing functions on the section methods
    • Transport all of our old JavaScript functions to section methods properties/function
    • New continued main.js
        methods: {
            InitializeBoardState: function() {
                this.LoadBoardState();
      
    • All internal function call references now need to start with a this reference so that they call the methods functions.

The fully upgraded version of Tic-Tac-Toe-Pro can be found on a new branch named convert-vue