VueNuxt.dev
Vue Insights

Code Readability

How to improve the readability of Vue code

Ref

Refs are fantastic, but their .value can give us much to discuss. I like to simplify this debate by keeping the following in mind:

  1. How can we distinguish between a mutation and just reading a value?
  2. How can we eliminate the possibility of introducing unintended side effects?
  3. How can we improve the code to read like natural language?

Example

Ref.ts
const optionA = ref('vue')
const optionB = ref('nuxt')

// I can work with this 
const choice = optionA.value
// but this is painful!
choice.value = optionB.value

// cluttered code logic with no semantic value
const msg = computed(() => `${optionA.value} & ${optionB.value} rock but ${choice.value} is best!`)

Insight

What if we save the ref.value syntax only to the left side of =. This order makes it explicit that we are mutating a reactive value.

For the right side of the =, we can use the helper functions toValue() or unref(). They both communicate that we are reading a reactive value and protect us from introducing side effects.

I favor toValue() over unref() because it improves the code's declarative language. Unref is more tied to the framework's implementation details.

Declarative language tells us what something does, while imperative language focuses on how something is done. Connecting the dots with declarative language while going over code is more effortless.

const optionA = ref('vue')
const optionB = ref('nuxt')

// this tells me it wont be reactive anymore
const choice = toValue(optionA)
// this signals we are getting a value from a reactive property
choice.value = toValue(optionB)

// strong visual cues, less cognitive load, no side-effects
const msg = computed(() => `${toValue(optionA)} & ${toValue(optionB)} rock but ${toValue(choice)} is best!`)

This simple convention gives everyone else and me clear visual boundaries of what is going on with a ref and its effects, decreasing the mental effort of reading the code.


Copyright © 2025