Computed Properties

Vue’s template syntax allows you to run any JavaScript code in your HTML

<div id="app">
  {{ message.split('').reverse().join('') }}
</div>

JavaScript in HTML

<div id="app">
  <h1>{{ message.split('').reverse().join('') }}</h1>
  <input v-model="message">
  <div>{{ message.split('').reverse().join('') }}</div>
  <span>{{ message.split('').reverse().join('') }} </span>
</div>

JavaScript in HTML

Not Easily Reusable

Extract this logic to Computed Properties

Extract logic to Computed Properties

<script>
  Vue.createApp({
    data() {
      return {
        message: 'To infinity and beyond'
      }
    },
    computed: {
      reversedMessage () {
        return this.message.split('').reverse().join('')
      }
    }
  }).mount('#app')
</script>

Extract logic to Computed Properties

<div id="app">
  {{ reversedMessage }}
</div>

Computed Properties

Re-Evaluate

Computed Properties

  • Act Like Getters
  • Eliminate Repetition
  • Re-Evaluate when their dependencies change

They are used to:

  • Perform Transformations and Computations

🔬Use Cases

Eliminate Repetition

<div id="app">
  <h1>{{ reversedMessage }}</h1>
  <input v-model="message">
  <div>{{ reversedMessage }}</div>
  <span>{{ reversedMessage }} </span>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        message: 'To infinity and beyond'
      }
    },
    computed: {
      reversedMessage () {
        return this.message.split('').reverse().join('')
      }
    }
  }).mount('#app')
</script>

Act like getters

<div id="app">
  <p v-if="isSunny">It's sunny today!</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        weather: 'sunny'
      }
    },
    computed: {
      isSunny () {
        return this.weather === 'sunny'
      }
    }
  }).mount('#app')
</script>

Act like getters

<div id="app">
  <p v-if="isSunny">It's sunny today!</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        weather: 'sunny'
      }
    },
    computed: {
      isSunny () {
        return this.weather === 'sunny'
      }
    }
  }).mount('#app')
</script>

Filter Data

<div id="app">
  <p v-for="item in itemsInStock" :key="item.id">{{ item.name }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        items: [
          {id: 1, name: 'Hat', quantity: 7, price: 498},
          {id: 2, name: 'Sock', quantity: 0, price: 59},
          {id: 3, name: 'Shoes', quantity: 4, price: 1189}
        ]
      }
    },
    computed: {
      itemsInStock() {
        return this.items.filter(item => item.quantity > 0)
      }
    }
  }).mount('#app')
</script>

Filter Data

<div id="app">
  <p v-for="item in itemsInStock" :key="item.id">{{ item.name }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        items: [
          {id: 1, name: 'Hat', quantity: 7, price: 498},
          {id: 2, name: 'Sock', quantity: 0, price: 59},
          {id: 3, name: 'Shoes', quantity: 4, price: 1189}
        ]
      }
    },
    computed: {
      itemsInStock() {
        return this.items.filter(item => item.quantity > 0)
      }
    }
  }).mount('#app')
</script>

Compute Data

<div id="app">
  <p>Cart total: {{ shoppingCartTotal }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        cart: [
          {name: 'Hat', quantity: 1, price: 498},
          {name: 'Sock', quantity: 3, price: 59},
          {name: 'Shoes', quantity: 1, price: 1189}
        ]
      }
    },
    computed: {
      shoppingCartTotal() {
        return this.cart.map(item => item.price * item.quantity)
          .reduce((total, amount) => total + amount)
      }
    }
  }).mount('#app')
</script>

Compute Data

<div id="app">
  <p>Cart total: {{ shoppingCartTotal }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        cart: [
          {name: 'Hat', quantity: 1, price: 498},
          {name: 'Sock', quantity: 3, price: 59},
          {name: 'Shoes', quantity: 1, price: 1189}
        ]
      }
    },
    computed: {
      shoppingCartTotal() {
        return this.cart.map(item => item.price * item.quantity)
          .reduce((total, amount) => total + amount)
      }
    }
  }).mount('#app')
</script>

Transform Data

<div id="app">
  <h1>Total is {{amountInDollars}}</h1>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        amount: 344
      }
    },
    computed: {
      amountInDollars () {
        return `$${this.amount}.00`
      }
    }
  }).mount('#app')
</script>

Transform Data

<div id="app">
  <h1>Total is {{amountInDollars}}</h1>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        amount: 344
      }
    },
    computed: {
      amountInDollars () {
        return `$${this.amount}.00`
      }
    }
  }).mount('#app')
</script>

Computed

VS

Methods

Computed

VS

Methods

  • Do not accept arguments
  • Never change the data
  • Should return a value
  • Re-evaluate based on dependencies
  • Accept arguments
  • Change the data
  • Returning a value is optional
  • Don't re-evaluate based on dependencies*
computed: {
  itemsInStock() {
    return this.items.filter(
      item => item.quantity > 0
    )
  }
}
methods: {
  setWeather (weather) {
    this.weather = weather
  }
}

Questions?

👩‍💻👨🏽‍💻 Assignment 1 (10 mins)

  1. display the candidates ordered by the number of votes where the more votes go higher - using a computed property
  2. display the name of the mayor (the candidate with the most votes) using a computed property

👩‍💻👨🏽‍💻 Assignment 1 (10 mins)

👩‍💻👨🏽‍💻 Assignment 2 (10 mins)

  • add a second list with the candidates that displays them in the original order

 

⚠️​ JavaScript sort alters the original array

💡computed properties should not have side effects

💡create a copy of the array or use a library like lodash

👩‍💻👨🏽‍💻 Assignment 3 (5 mins)

  • Display the total amount of voters.

Vue Composition API Workshop

February 2nd 2023

Vue School Courses

Components

  // Create a Vue application
const app = Vue.createApp({})

// Define a new global component called button-counter
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
})

Vue Devtools

Closing Remarks, Next Steps, and Q&A

Filters

Vue 2

Filters

Transform a value before displaying it to the user

<div id="app">
  <h1>{{ message | capitalize }}</h1>
</div>

Filter

For Example

  • Display a date to user's local timezome
  • Display an amount in a currency format

Filters

are only available in the template

they are similar to computed and methods

Filters

Vue 3

BUT

Transforming values is an essential feature in Vue

Vue 3

Transform values in

also works in Vue 2

Vue 3

In

to implement "filter" functionality, we use methods and computed

No arguments?

use a computed

<div id="app">
  <h1>Total is {{amountInDollars}}</h1>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        amount: 145
      }
    },
    computed: {
      amountInDollars () {
        return `$${this.amount}.00`
      }
    }
  }).mount('#app')
</script>

Need to pass arguments?

use a method

<div id="app">
  <h1>Total is {{dollars(amount, 2)}}</h1>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        amount: 145
      }
    },
    methods: {
      dollars (amount, decimals = 0) {
        return '$' + this.amount.toFixed(decimals)
      }
    }
  }).mount('#app')
</script>

Questions?

Let me take a selfie

1. create a computed property or a method that transforms a given timestamp to the current time

 

Example

timestamp: 1610643160

time: 17:52

 

Hint: Use the JavaScript Date to format the time or a 3rd party library of your choice.

 

👩‍💻👨🏽‍💻 Assignment 1 (5 mins)

🥐 BREAK - 20 mins

👋 Welcome

Today's Outline

  1. Vue Devtools and Class Bindings
  2. Components
  3. Component Communication
  4. Practical Exam
  5. Q&A

Vue Devtools

Vue Devtools

  • Google Chrome
  • Firefox
  • Standalone App

 

Vue Devtools

DEMO

Vue Devtools

Install it now 🙃

Vue Devtools

in Static files

Vue Devtools

in Static files

Vue Devtools

Keep it open while you work on Vue code 💪

Questions?