Double-check all the Vue best practices that are easiest to forget when you’re focused on design and business logic, but hardest to catch with automated tooling.
The answer to every question should be “yes”, and you should aim to spend 10-15 minutes on the entire list after you’ve already had a chance to read and understand the code.
- Is reactive state created & managed where it's needed, instead of further up the component or composable tree?
- Is prop drilling avoided, within reason?
- Is state derived with
computed
when possible, instead of synced? - If there's any reactive state that should only update the app when the entire piece of state is replaced, has
shallowRef
been used instead ofref
?
- Are
.reduce()
callbacks reasonably readable? - Have iterations been avoided or simplified as often as possible for performance and/or readability?
Common iterations to look for:
.concat(
.every(
.filter(
.find(
.findIndex(
.forEach(
.includes(
.indexOf(
.join(
.map(
.reduce(
.slice(
.some(
.sort(
for(
- Is it obvious enough?
- Can it be made more readable and/or efficient with memoized state?
- If the list gets reactively reordered by user interaction, do items have a unique key other than the index of the item?
- Are browser APIs always accessed after the component mounts?
- Are watchers set to
flush: 'post'
if they perform side effects on DOM elements rendered by Vue? - Are
computed
callbacks devoid of side effects?
- Are errors & failed requests caught and tracked?
- When appropriate, are loading animations and error messages rendered?
- Can types, especially
any
types, be narrowed?
- Has lower level, commonly-needed UI logic & reactive state been extracted to composables?
- Have directives, mixins, and renderless components been replaced by composables whenever possible?
Code organization (further study)
- Inside composables, has a separation section of code been marked for each logical concern? (Usually, 1-3
ref
orcomputed
calls form the foundation of a separate logical concern and a separate section of code) - Do sections of code have a consistent order? E.g. start with reactive state, then write methods, then write side effects.
- Are functions and side effects defined reasonably close to any reactive state they interact with?
- Have you avoided the temptation to mix concerns inside watchers, lifecycle hooks, and event handlers?
- Is organization consistent?