Vue.js CheatSheet

Table of Contents

1. Hello World!

Vue.js enhances HTML by giving it a dynamic layer; i.e., raw HTML just displays things, but with Vue.js we can have parts shown according to, say, input boxes and variables (which raw HTML does not have). [See also the JavaScriptCheatSheet PDF.]

An example is worth a thousand words!

<html >
  <!-- ⟨0⟩ Actually load Vue.js -->
  <script src="https://unpkg.com/vue@3"></script>
  <body>
      <div id="hello">  <!-- ⟨1⟩ Vue.js is active for this div; see ⟨4⟩ -->

          <!-- ⟨2⟩ The *value* of this text box is named “yourName” -->
          <input v-model="yourName" placeholder="Enter a name here">

          <!-- ⟨3⟩ Actually use the “yourName” value here,
               *whenever* it is updated! -->
          <h1>Hello {{yourName.toUpperCase()}}!</h1>
      </div>

      <!-- ⟨4⟩ Setup the associated model for “#hello” -->
      <script>
       let myApp = Vue.createApp({
           data() {
               return {
                   yourName: 'Jason'
               }
           }
       }).mount('#hello')

       // Here, we can perform complex logic (JS code) on “myApp.yourName”.
       // Vue.js automatically keeps the HTML view and the JS model in sync.
       myApp.yourName = 'Jasim'
      </script>
  </body>
</html>

This is a self-contained interactive program: Whenever the input box's value is changed then so is the greeting header “Hello …!”.

Bindings like {{this}} are known as mustache tags, which tell Vue.js that it should evaluate an expression and insert the result into the DOM in place of the binding. Rather than a one-time insert, a binding will result in efficient continuous updates whenever the result of the expression evaluation changes.

Finally, Vue.js is reactive: If you open your browser's console, and evaluate myApp.yourName = 'Bob', then the HTML view changes!

Exercise! Using <input type="number" ...>, make a super simple site with two input boxes for numbers and a header that shows their sum whenever a user inputs values. (Hint! Use Number(x) to convert a string x to a number.)

  • A page can be associated with multiple Vue.js apps, and the id-dentifier attribute specifies which HTML element views an app.

2. Vue.js makes HTML into a language with variables and control flow

Vue.js enhances HTML with variables, filters (explained below), arrays, JSON Objects, and looping & conditional control flow —using JS's usual &&, ||, ==, etc for Booleans. Later we'll see that functions can be defined in an associated controller, then used in the view.

<html>
  <script src="https://unpkg.com/vue@3"></script>
  <body>
    <div id="app">

      <!-- VARIABLES [Not reccommended, better use “data” below.] ---------------->
      <!-- Let's declare a var, but hide the resulting value from view -->
      <p hidden>  {{  love = 'JavaScript'  }}  </p>
      <!-- Use the variable -->
      {{ love + " is cool" }} <br> <br>

      <!-- APPLICATION: Keeping count. Definitions are in “data” and “methods” below. -->
      <button v-on:click="increment">        Increment      </button>
      Count: {{count}}

      <!-- Inline multiple actions; only works with proper v-model variables; i.e. not “love” above. -->
      <!-- “age” is declared below in “data”. -->
      <label> <input type="checkbox" v-model="isItOn" @click="count += 40, age += 2" /> {{ isItOn }} </label>

      <!-- ARRAYS & JSON OBJECTS -------------------------------------------------------->
      <!-- Lets make an array of objects ... -->
      {{  people = [ {name: 'kathy', age: 32}
                   , {name: 'bob', age: 12}
                   , {name: 'jasim', age: 114}
                   ]  }}

      <!-- APPLICATION: Search box, searching by name ----------------------------->
      <br> Search: <input v-model="query" placeholder="Search by name" />
      <br> Results: {{ people.filter(p => p.name.includes(this.query.toLowerCase())) }}

      <!-- LOOPING ------------------------------------------------------->
      <!-- No more hardcoded lists! -->
      <!-- v-for creates a <li> element for each element in the list,
           using the <li> tag as the template. -->
        <ul>
            <li v-for="p in people">
                {{p.name + ' is ' + p.age + ' years old!' }}
            </li>
        </ul>

      <!-- CONDITIONALS -------------------------------------------------->
      <!-- Name this inputs box's value ‘age’ -->
      <input type="number" v-model="age" placeholder="Your age">
      <!-- “Hello” is shown whenever the above ‘age’ input is truthy/non-zero. -->
      <p type="text" v-if="age"> Hello! </p>
      <!-- This input box shows only if the above, ‘age’, has value 12. -->
      <input type="text" v-if="age == 12" placeholder="Your name?">

    </div>
    <!-- The model for the above content. -->
    <script>
     let app = Vue.createApp({
         data() {
             return { count: 0
                    , isItOn: false
                    , query: ''
                    , age: 0
                    , people: []
             }
         },
        methods: {
            increment: function () {this.count++}
        }
     }).mount('#app')
    </script>

    <!-- PUTTING IT ALL TOGETHER: A TODO APP IN ≈30 LINES --------------------------------->
    <hr>
    <div id="todo-app">
      <input placeholder="Enter a new TODO item and press ENTER" size="40"
             v-model="newTodo" v-on:keyup.enter="addTodo">
      <ul>
        <li v-for="(todo, index) in todos">
          <span> {{ todo.text }} </span>
          <button v-on:click="removeTodo(index)">X</button>
        </li>
      </ul>
    <!-- Always refers to whatever is CURRENTLY the first item in “todos”. -->
    <a :href=`https://www.google.com/search?q=${todos[0].text}`>I'm feeling lucky!</a>
    </div>
    <script>
     Vue.createApp({
         data() {
             return { newTodo: ''
                    , todos: [ { text: 'Add some todos' } ]
             }
         },
         methods: {
             addTodo () {
                 var text = this.newTodo.trim()
                 if (text) {
                     this.todos.push({ text })
                     this.newTodo = ''
                 }
             },
             removeTodo (index) {
                 this.todos.splice(index, 1)
             }
         }
     }).mount('#todo-app')
    </script>
  </body>
</html>

<!-- VARIABLES --> To let users interact with your app, use the v-on directive to attach event listeners. In our case, we have a variable whose value increases with each user click.

Note that arbitrary JS expressions will not be evaluated in moustaches; for that, we use the methods object when declaring our app. Then, in that method we do our arbitrary JS and that method is the one we can call in moustaches (within our div).

<!-- LOOPING --> We are using the HTML tags of <ul> (Unordered List) and <li> (List Item) to display the list of items in our array. The v-for optionally has a second argument, to refer to the looping index; it can also destructure its argument, loop over a single object's value-key pairs, and loop over ranges.

<!-- CONDITIONALS --> When the condition to v-if is falsy, the HTML element is removed from the DOM; otherwise it's added to the DOM. In contrast, v-show merely turns off the display. (v-if vs v-show). There are also v-else and v-else-if.

<!-- TODO APP. v-bind:𝒳 ≈ :𝒳 --> Vue.js provides HTML directives that “already exist” but know how to evaluate expressions; e.g., <a href="{{expr}}">Go!</a> would not evaluate expr, for that we use <a v-bind:href=`${expr}`>Go!</a> with backticks (ES6 templates). Since v-bind: is so useful, there is a brief alias: <a :href=`${expr}`>Go!</a>.

( Filters are removed from Vue 3.0 and no longer supported. )

Exercise! Get a twitter handle from the user and show a link to that twitter page.

3.  :class Bindings

<!-- HTML is so permissive that this will load fine even though we're missing <html> and <body> tags. -->
<script src="https://unpkg.com/vue@3"></script>

<div id="app">
    <h1 :class="isRed ? 'r' : 'b'"> Hello <h1>
</div>

<style>
.r {color: red;}
.b {color: blue;}
</style>

<script>
 Vue.createApp({ data() { return { isRed: false } }
 }).mount('#app')
</script>

4. Computed Data ~ Reactive Variables

<!-- HTML is so permissive that this will load fine even though we're missing <html> and <body> tags. -->

<div id="app">
    {{ count }} * 2 = {{ double }}
    <br> <button @click="count++">+</button>
</div>

<script src="https://unpkg.com/vue@3"></script>
<script>
 Vue.createApp({ data()    { return { count: 0 } }
               , computed: { double() { return this.count * 2 } }
 }).mount('#app')
</script>

5. Watchers

<!-- HTML is so permissive that this will load fine even though we're missing <html> and <body> tags. -->
<script src="https://unpkg.com/vue@3"></script>

<div id="app">
    Data: {{ d }};
    Watcher: {{ w }}
    <br> <button @click="d++">+</button>
</div>

<script>
 Vue.createApp({ data() { return { d: 1, w: 1 } }
               , watch: { d() { this.w = this.d * 2 } }
 }).mount('#app')
</script>

Author: Musa Al-hassy

Created: 2022-03-24 Thu 10:03

Validate