A Full Day of Vue.js

02. The Vue Instance II

Methods, Computed Properties, Watchers, & Lifecycle Hooks

The Vue Instance is the heart of a Vue application. All Vue applications begin with the Vue instance.

The Vue Instance

new Vue({});

options

new Vue({
  el: '#app',
});

The Vue Instance

new Vue({
  el: '#app',
});
<body>
  <div id="app"></div>
</body>

The Vue Instance

The Vue Instance - Data

new Vue({
  el: '#app',
  
});


  data: {}

Methods() are bound to the instance and behave like normal JavaScript functions - evaluated when explicitly called.

methods: {
  methodName() {}
}

Syntax

The Vue Instance - Methods

new Vue({
  el: '#app',
  data: {
    message: 'Greetings!',
  },
});
<div id="app">
  <div class="card">
    <header class="card-header card-header-title">
      <span>Original:</span> {{ message }}
    </header>
    
    <header class="card-header card-header-title">
      <span>Reversed:</span> {{ message.split('').reverse().join('') }}
    </header>
  </div>
</div>

The Vue Instance - Methods

new Vue({
  el: '#app',
  data: {
    message: 'Greetings!',
  },
  methods: {
    reverseString(string) {
      return string.split('').reverse().join('');
    },
  }
});
<div id="app">
  <div class="card">
    <header class="card-header card-header-title">
      <span>Original:</span> {{ message }}
    </header>
    
    <header class="card-header card-header-title">
      <span>Reversed:</span> {{ reverseString(message) }}
    </header>
  </div>
</div>

The Vue Instance - Methods

The Vue Instance - Methods

Methods are also useful when it comes to dealing with DOM events.

The Vue Instance - Methods

Methods can handle complicated functionality as well.

The Vue Instance - Computed Properties

Computed properties are used to handle complex calculations to data that need to be displayed in the view.

computed: {
  computedName() {}
}

Syntax

The Vue Instance - Computed Properties

new Vue({
  el: '#app',
  data: {
    message: 'Greetings!',
  },
  computed: {
    reverseMessage() {
      return this.message.split('').reverse().join('');
    },
  }
});
<div id="app">
  <div class="card">
    <header class="card-header card-header-title">
      <span>Original:</span> {{ message }}
    </header>
    
    <header class="card-header card-header-title">
      <span>Reversed:</span> {{ reverseMessage }}
    </header>
  </div>
</div>

The Vue Instance - Computed Properties

What's the difference between using a computed property or returning the value of a method?

The Vue Instance - Computed Properties

new Vue({
  // ....
  computed: {
    reverseMessage() {
      return this.message.split('').reverse().join('');
    },
  }
});
new Vue({
  // ....
  methods: {
    reverseString(string) {
      return string.split('').reverse().join('');
    },
  }
});

In this example, they achieve the exact same outcome.

The Vue Instance - Computed Properties

Key difference is: computed properties are cached based on the dependencies they depend on!

The Vue Instance - Computed Properties

computed: {
  reverseMessage() {
    return this.message.split('').reverse().join('');
  }
}

computed property

dependancy

The Vue Instance - Computed Properties

computed: {
  reverseMessage() {
    return this.message.split('').reverse().join('');
  }
}

When message remains constant

{{ reverseMessage }}
{{ reverseMessage }}
{{ reverseMessage }}
{{ reverseMessage }}

All return the same cached value without running the function

The Vue Instance - Computed Properties

new Vue({
  el: '#app',
  data: {
    message: 'Greetings!',
  },
  computed: {
    reverseMessage() {
      return this.message.split('').reverse().join('');
    },
  }
});
<div id="app">
  <div class="card">
    <header class="card-header card-header-title">
      <span>Original:</span> {{ message }}
    </header>
  </div>
  
  <div class="card">
    <header class="card-header card-header-title">
      <span>Reversed:</span> {{ reverseMessage }}
    </header>
  </div>
  
  <div class="card">
    <header class="card-header card-header-title">
      <span>Reversed:</span> {{ reverseMessage }}
    </header>
  </div>
  
  <div class="card">
    <header class="card-header card-header-title">
      <span>Reversed:</span> {{ reverseMessage }}
    </header>
  </div>
</div>

Computed

The Vue Instance - Computed Properties

Methods

Functions that are meant to be called

Intended to compute existing data

Can have parameters passed in

Can't (?) have parameters passed in

Re-evaluated every time their called

Cached based on their dependencies

Should be used as a property

Not meant to be a property

The Vue Instance - Computed Properties

A good pattern to follow

  • Use computed properties for data manipulation

  • Use methods to invoke changes

The Vue Instance - Computed Properties

Have submissions sorted from highest number of upvotes to lowest number.

new Vue({
  ...
  data: {
    submissions
  },
  computed: {
    sortedSubmissions() {
      const initialSubmissions = this.submissions;
​      return initialSubmissions.sort((a, b) => {
        return b.votes - a.votes;
      })
    }
  }
});
new Vue({
  ...
  data: {
    submissions
  },
  computed: {
    sortedSubmissions() {
      const initialSubmissions = this.submissions;
​      return initialSubmissions.sort((a, b) => {
        return b.votes - a.votes;
      })
    }
  }
});

Watchers allow us to react to data changes.

watch: {
 dataProperty(oldValue, newValue) {}
}

Syntax

The Vue Instance - Watchers

new Vue({
  el: '#app',
  data: {
    input: '',
    counter: 0,
  },
  watch: {
    input() {
      this.counter++;
    },
  }
});
<div id="app">
  <div class="field">
    <label class="label">Input</label>
    <input v-model="input"
           class="input"
           type="text"
           placeholder="Type something!">
  </div>
  
  <div class="card">
    <header class="card-header card-header-title">
      <span>Changes made:</span> {{ counter }}
    </header>
  </div>
</div>

The Vue Instance - Watchers

"Watchers are most useful when you want to perform asynchronous or expensive operations in response to data changes."

The Vue Instance - Watchers

Lifecycle hooks are named functions that occur throughout the lifecycle of a Vue instance.

The Vue Instance - Lifecycle Hooks

The Vue Instance - Lifecycle Hooks

The Vue Instance - Lifecycle Hooks

The Vue Instance - Lifecycle Hooks

The Vue Instance - Lifecycle Hooks

Lifecycle Hooks

beforeCreate()
created()
beforeMount()
mounted()
beforeUpdate()
updated()
beforeDestroy()
destroyed()

The Vue Instance - Lifecycle Hooks

The Vue Instance - Lifecycle Hooks

Vue gives us these hooks where we can insert our own functionality at different times in the instance's lifecycle.

The Vue Instance - Lifecycle Hooks

Lifecycle Hooks

beforeCreate()
created()
beforeMount()
mounted()
beforeUpdate()
updated()
beforeDestroy()
destroyed()

Instance is being created

Instance is being mounted

Instance is being updated

Instance is being destroyed

The Vue Instance - Lifecycle Hooks

created()

Since the created hook is run the moment an instance has been created but before the DOM has been mounted/rendered, it’s often the ideal moment to fetch data that is needed to populate the instance.

new Vue({
  el: '#app',
  data: {
    name: "Loading...",
    email: "Loading...",
    company: {
      name: "Loading...",
      catchPhrase: "Loading...",
    }
  },
  created() {
    axios.get('https://jsonplaceholder.typicode.com/users')
      .then((response) => {
        const data = response.data;
        const randomUser = response.data[Math.floor(Math.random() * data.length)];
 
        this.name = randomUser.name;
        this.email = randomUser.email;
        this.company.name = randomUser.company.name;
        this.company.catchPhrase = randomUser.company.catchPhrase;
      });  
  },
});

The Vue Instance - Lifecycle Hooks - created()

<div id="app">
  <div class="card">
    <header class="card-header">
      <p class="card-header-title">
        {{name}}
      </p>
    </header>
    <div class="card-content">
      <div class="content">
        <p>{{company.name}}</p>
        <p>"{{company.catchPhrase}}"</p>
      </div>
    </div>
    <footer class="card-footer">
      <a href="#" class="card-footer-item">{{email}}</a>
    </footer>
  </div>
</div>

The Vue Instance - Lifecycle Hooks - created()

The Vue Instance - Lifecycle Hooks

mounted()

The mounted() hook is run after the instance has been mounted and where the rendered DOM can be accessed.

The Vue Instance - Lifecycle Hooks

new Vue({
  el: '#app',
  data: {
    name: "Loading...",
    email: "Loading...",
    company: {
      name: "Loading...",
      catchPhrase: "Loading...",
    }
  },
  created() {
    // ...  
  },
  mounted() {
    console.log(this.$el);
  }
});

The Vue Instance - Lifecycle Hooks

updated()

The updated() hook gets fired whenever a data change is made that causes the instance to be updated/re-rendered.

vm.$el

Rendered DOM after the update has been made

Instance is being mounted

Best used when DOM-dependant changes are needed

The Vue Instance - Lifecycle Hooks

Instance is being updated

The Vue Instance - Lifecycle Hooks

destroyed()

The destroyed() hook is fired after an instance has been fully destroyed. Useful any last minute changes when the instance is ever completely removed.

 The Vue Instance - Chapter Summary!

  • Methods are evaluated when explicitly called. 

  • Computed properties are used to perform more complex calculations/manipulation to data values and are cached.

  • Watchers allow us to react to data changes.

  • Lifecycle hooks are functions that run through the lifecycle of a Vue instance.

  • beforeCreate()/created()
  • beforeMount()/mounted()
  • beforeUpdate()/updated()
  • beforeDestroyed()/destroyed()

 The Vue Instance - Chapter Exercise 💪!

1

 The Vue Instance - Chapter Exercise 💪!

Starting Point

1

 The Vue Instance - Chapter Exercise 💪!

Goals

- Use axios.get call within a created lifecycle hook. Update a new data array property.

  • Render a list of user cards with the help of the v-for directive.

- Place the v-for directive on the element that we'd want repeated!

  • Have the users list be ordered in reverse

- Create a computed property that reverses the user list (e.g. Array.reverse())

1

Solution 👀

 The Vue Instance - Chapter Exercise 💪!

2

 The Vue Instance - Chapter Exercise 💪!

Starting Point

2

 The Vue Instance - Chapter Exercise 💪!

Goals

  • When the user types in one input; watch the other input and derive its intended value.

- Use the watch: {} property.

- Watch both properties to derive each input when the other is being entered.

Solution 👀

2

Made with Slides.com