watch & Composables — Series 3

Preview — 3 of 10 questions

What are newA/newB and oldA/oldB when both a and b change in the same tick?

javascript
import { ref, watch } from 'vue'

const a = ref(1)
const b = ref('x')

watch([a, b], ([newA, newB], [oldA, oldB]) => {
  console.log(newA, newB, oldA, oldB)
})

a.value = 2
b.value = 'y'
Awatch only accepts a single source; passing an array throws a compile-time error
Bwatch accepts an array of sources and passes matching arrays of new/old values to the callback — here it logs 2 'y' 1 'x', since both changes are batched into the same callback invocation rather than firing the callback twice
CIt fires the callback twice, once per changed source, each time with only that source's before/after values
DOnly the first source in the array (a) is actually watched; b is ignored

Does this work, and what does total show for price = 100, taxRate = 0.2?

javascript
import { ref, computed } from 'vue'

const price = ref(100)
const taxRate = ref(0.2)

const tax = computed(() => price.value * taxRate.value)
const total = computed(() => price.value + tax.value)
AIt's invalid — a computed can only read plain ref/reactive sources, never another computed
Btax and total both compute once at declaration time and never update again, since chaining computeds breaks dependency tracking
Ctotal silently ignores tax and just re-adds price.value to itself
DThis is perfectly valid — total reads tax.value, so tax becomes one of total's tracked dependencies too. total is 120 (100 + 100*0.2), and changing price or taxRate correctly recomputes tax first, which then correctly invalidates and recomputes total as well, cascading through the chain

What does the third argument (true) change here?

javascript
import { inject } from 'vue'

const logger = inject('logger', () => new ConsoleLogger(), true)
AWithout inject's optional third true argument, when no provider exists, the second argument is normally used as-is — treated directly as the fallback value. When that default happens to be a function (like a factory here) and you actually want the default value itself to be a function (rather than calling it to produce the default), you'd need this differently; the third true argument tells Vue to instead treat the second argument as a factory and call it to produce the default, only when no provider was found
Btrue makes the injection required — it throws if no provider exists, ignoring the default entirely
Ctrue makes the inject call reactive, re-running the factory every time any provided value in the app changes
DThe third argument has no effect; it's silently ignored by inject

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.