ref()

When using the Vue.js composition API, it is recommended to use the ref() function to created reactive state. The ref() function is a wrapper for a value, and when the value changes, Vue automatically update any parts of the template that use that value.

Syntax

const value = ref(initialValue);

Parameters:

  • initialValue: The initial value for the ref. Can be any type (string, number, array, boolean, object, etc.)

Return value:

  • Returns a reactive object with a .value property that holds the actual value. Using .value is not required to access values in the <template>, e.g:
<script setup>
  const name = ref("Homer");
  console.log(name.value);
</script>

<template>
    <p>User: {{ name }}</p>
</template>

Basic usage

Here's a simple example of using ref() to update a user name (string value):

<script setup>
import { ref } from 'vue';

const name = ref("Homer");

function changeUser() {
    name.value = "Bart";
}
</script>

<template>
  <div>
    <p>User: {{ name }}</p>
    <button @click="changeUser">Change User</button>
  </div>
</template>
  • Import ref from the vue package to use.
  • Use the .value property to access or modify the value (E.g. name.value).
  • The variable name can be used directly in the template (E.g. {{ name }}).

The above example uses <script setup> to simplify single-file components. Alternatively, setup() can be used to integrate Composition-API code into the Options API:

<script>
import { ref } from 'vue';
export default {
  setup() {
    const name = ref("Homer");

    function changeUser() {
      name.value = "Bart";
    }

    // return to use in the template
    return {
      count,
      changeUser
    }
  }
}
</script>

📝 Note: The remaining examples will be <script setup> based.

Refs with objects

When using refs with objects, the entire object becomes reactive:

const user = ref({
  name: 'Homer',
  occupation: 'Nuclear Safety Inspector',
  likesDonuts: false
});

user.value.likesDonuts = true;
console.log(user.value);
// {name: 'Homer', occupation: 'Nuclear Safety Inspector', likesDonuts: true}

Refs with arrays

Refs can also produce reactive arrays:

const family = ref(['Homer', 'Marge', 'Bart', 'Lisa']);

family.value.push('Maggie');

Practical example

Here's an example of using ref() in a pizza order component:

<script setup>
import { ref } from 'vue';

const pizzaSize = ref('medium');
const toppings = ref(['cheese', 'tomato']);

function addTopping(topping) {
  toppings.value.push(topping);
}

function removeTopping(topping) {
  toppings.value = toppings.value.filter(t => t !== topping);
}
</script>

<template>
  <div class="pizza-order">
    <h3>Build Your Pizza &#x1F355;</h3>

    <div class="size-selector">
      <label>Size:</label>
      <select v-model="pizzaSize">
        <option value="small">Small</option>
        <option value="medium">Medium</option>
        <option value="large">Large</option>
      </select>
    </div>

    <div class="toppings">
      <h4>Toppings ({{ toppings.length }}):</h4>
      <ul>
        <li v-for="topping in toppings" :key="topping">
          {{ topping }}
          <button @click="removeTopping(topping)">Remove</button>
        </li>
      </ul>

      <button @click="addTopping('pepperoni')">Add Pepperoni</button>
      <button @click="addTopping('ham')">Add Ham</button>
      <button @click="addTopping('mushrooms')">Add Mushrooms</button>
      <button @click="addTopping('onions')">Add Onions</button>
    </div>
  </div>
</template>

TypeScript support

When using TypeScript, you can specify the ref type:

const number = ref<number>(1);
const message = ref<string>('Vue.js refs');

Common uses

Binding form inputs

<script setup>
import { ref } from 'vue';

const username = ref('');
const password = ref('');

function handleSubmit() {
  console.log('Username:', username.value);
  console.log('Password:', password.value);
}
</script>

<template>
  <form @submit.prevent="handleSubmit">
    <input v-model="username" type="text" placeholder="Username">
    <input v-model="password" type="password" placeholder="Password">
    <button type="submit">Submit</button>
  </form>
</template>

Toggling state

<script setup>
import { ref } from 'vue';

const showOptions = ref(false);

function toggleOptions() {
  showOptions.value = !showOptions.value;
}
</script>

<template>
  <button @click="toggleOptions">
    {{ showOptions ? 'hide' : 'show' }}
  </button>
  <div v-if="showOptions">
    This content is now visible!
  </div>
</template>

📝 Note: Remember, ref() is only available in the Composition API. For the Options API, use the data option instead.