Watching the World

Go By

A Jaunty Stroll Through watch and watchEffect

Alex Riviere

  • Atlanta Vue.js Meetup organizer
  • Front-end Developer
  • Likes cats.
Q: What's a pirate's favorite programming language?

(most of the time)

watch and watchEffect

Today's Topic:

A: You'd think it was R, but their first love is the C.

Computed values

import {ref, computed} from 'vue';

const counter = ref(0);

const doubleCounter = computed(()=>counter.value*2);

counter.value = 2;

console.log(doubleCounter.value); // 4
Q: What accommodations did the JavaScript developer request at the hotel?

Computed values

  • Values get computed once and are cached
  • Can also have a dynamic setter
  • Not asynchronous
A: A room with a Vue.
Q: Why did the computer spy quit?

watchEffect

  • Runs immediately
  • Tracks all reactive values accessed inside of it
  • Runs every time any value is updated

basic watchEffect

A: They couldn’t hack it anymore!
import {ref, watchEffect} from 'vue';

const paint = ref('wet');

watchEffect(()=>{
  console.log('watching paint:', paint.value)
}); 
// logs 'watching paint:', 'wet'

paint.value = 'dry' 
// logs 'watching paint:', 'dry'
Q: What do you get when you cross a computer with a hamburger?

Stopping watchEffect

<template>
  <h1>Water temperature: {{ waterTemp }}</h1>
  <button @click="stopWatching">Stop watching</button>
</template>
<script>
import { ref, watchEffect } from 'vue';
export default {
  setup() {
    const waterTemp = ref(100);

    const stopWatching = watchEffect(() => {
      if (waterTemp.value === 212) {
        waterTemp.value = 211;
      }
    });

    setInterval(() => waterTemp.value++, 250);

    return {
      waterTemp,
      stopWatching
    };
  }
};
</script>
A: A Big Mac!

Stopping watchEffect

Q: What do you say when a JavaScript interview went bad?

onInvalidate cleanup

<template>
  <h1>Water temperature: {{ waterTemp }}</h1>
  <label>Heat: <input type="checkbox" v-model="heat" /></label>
</template>
<script>
import { ref, watchEffect } from 'vue';
export default {
  setup() {
    const waterTemp = ref(100);
    const heat = ref(true);

    watchEffect((onInvalidate) => {
      const amount = heat.value ? 1 : -1;
      const interval = setInterval(
        () => (waterTemp.value += amount),
        1000
      );
      onInvalidate(() => {
        clearInterval(interval);
      });
    });
    return { waterTemp, heat };
  }
};
</script>
A: Don't call us, we'll callback you. We promise!

onInvalidate cleanup

Q: How do you comfort a JavaScript bug?

watchEffect Options param

watchEffect has a second param that is an options object. It has 3 properties:

  • flush
  • onTrack
  • onTrigger
A: You console it!

watchEffect Options param

flush:"pre"|"post"|"sync"
  • first run of watchEffect is always "sync"
  • when watchEffect is triggered
    • "pre" runs callback before component updates
    • "post" after component updates
    • "sync" runs it synchronously.
  • "pre" is the default.
Q: Why was the database admin kicked out of the bar?

watchEffect Options param

onTrack:function(DebugEvent)
  • can be set as a callback
  • triggers when a value is tracked by watchEffect
  • only runs in development mode.
A: They kept joining the tables.

watchEffect Options param

onTrigger:function(DebugEvent)
  • can be set as a callback
  • runs when watchEffect is triggered by tracked value updating
  • only runs in development mode.

Let's Talk About watch

Q: What is the biggest lie in the entire universe?

watch is similar to watchEffect but allows you to specify the values tracked. It also allows you to receive the previous value for comparison.

A: 'I have read and agree to the Terms & Conditions.'

Watch your Mouth

import { ref, reactive, watch } 
	from 'vue';
export default {
  setup() {
    const mouth = ref("");
    const language = reactive([]);
    watch(
      mouth, 
      (mouth, prevMouth) => {
        language.unshift(
          { mouth, prevMouth }
        );
      }
    );
    return { mouth, language };
  }
};
<label>
  <h1>Watch your Mouth</h1>
  <input type="text" v-model="mouth" />
</label>
<ul>
  <li v-for="entry in language">{{ entry }}</li>
</ul>
import { toRefs, reactive, watch } 
	from 'vue';
export default {
  setup() {
    const state = reactive({
      mouth: "", language: []
    });
    watch(
      ()=>state.mouth, 
      (mouth, prevMouth) => {
        state.language.unshift(
          { mouth, prevMouth }
        );
      }
    );
    return { ...toRefs(state) };
  }
};
Q: What do you call a Rails developer?

Watch your Mouth

A: A conductor!

Watch your Six

const { ref, reactive, watch } = Vue;
export default {
  setup() {
    // directly watching multiple refs
    //one, two, three, four, five, six
    const one = ref("red");
    const two = ref("red");
    const three = ref("red");
    const four = ref("red");
    const five = ref("red");
    const six = ref("red");

    const history = reactive([]);
    watch(
      [one, two, three, four, five, six], 
      (positions, prevPositions) => {
      	history.unshift({ positions, prevPositions });
    });
    return { one, two, three, four, five, six, history };
  }
};
Q: Why couldn't the programmer dance to the song?

Watch your Six

A: Because they didn't get the algo-rhythm!

watch and reactive objects

import { ref, reactive, watch } from 'vue';
export default {
  setup() {
    const grass = reactive([]);
    const oldSize = ref(0);
    const size = ref(0);
    watch(grass, (grass, prevGrass) => {
      oldSize.value = prevGrass.length;
      size.value = grass.length;
    });

    setInterval(() => grass.push("🌱"), 1000);
    return { grass, oldSize, size };
  }
};
Q: Why don't programmers like nature?

Watching Grass Grow?

A: Too many bugs!

watch and reactive objects

import { ref, reactive, watch } from 'vue';
export default {
  setup() {
    const grass = reactive([]);
    const oldSize = ref(0);
    const size = ref(0);
    watch(
      () => [...grass],
      (grass, prevGrass) => {
        oldSize.value = prevGrass.length;
        size.value = grass.length;
      }
    );
    setInterval(() => grass.push("🌱"), 1000);
    return { grass, oldSize, size };
  }
};
Q: Why did the programmer stop using Python?

Watching Grass Grow

A: Because they are scared of snakes!

Final Tip

When watching reactive objects in vue 3:

Watch your step.

Jokes provided by https://puns.dev

Thank you.

Questions?

Watching the World Go By

By Alex Riviere

Watching the World Go By

a jaunty stroll through watch and watchEffect

  • 628