Understanding and Using "ref" in Vue 3
Vue 3, the latest iteration of the popular JavaScript framework, brings a multitude of features and improvements that enhance the development experience. Among these, the ref
function stands out as a vital tool for Vue developers. In this blog post, we'll dive into what ref
is, how it works in Vue 3, and its practical applications in building reactive interfaces.
What is ref
in Vue 3?
In Vue 3, ref
is a function imported from the Vue package that creates a reactive reference to a value. When you wrap a value with ref
, Vue tracks changes to that value, ensuring the UI updates whenever the value changes. This is part of Vue's reactivity system, which is now powered by JavaScript's Proxy object.
Syntax and Basic Usage
import { ref } from 'vue';
const myValue = ref(initialValue);
Here, myValue
becomes a reactive reference to initialValue
. It's important to note that to access or modify the value of myValue
, you need to use myValue.value
.
How Does ref
Work?
Under the hood, Vue 3's reactivity system uses Proxies to observe changes to values. When you use ref
, it creates a reactive and mutable object with a single property value
. This value
property is the actual data you want to be reactive. Whenever you access or modify myValue.value
, Vue tracks these changes and updates the DOM accordingly.
Practical Applications of ref
1. Local State in Components
One of the most common uses of ref
is to manage local state within a component. For example, you might use ref
to keep track of a user's input in a form.
<script setup>
import { ref } from 'vue';
const username = ref('');
</script>
In your template, you can easily bind this reactive reference:
<input v-model="username.value" />
2. Reactive Properties Outside of data
Option
In Vue 2, reactive properties were typically declared inside the data
option of a component. With Vue 3 and the Composition API, ref
allows you to define reactive properties outside the data
option, giving you more flexibility in structuring your component's logic.
3. Interacting with DOM Elements
ref
can also be used to create a reference to a DOM element. This is particularly useful when you need to directly interact with an element, like focusing on an input or integrating with third-party libraries that need direct DOM access.
<script setup>
import { ref, onMounted } from 'vue';
const inputEl = ref(null);
onMounted(() => {
inputEl.value.focus();
});
</script>
<template>
<input ref="inputEl" />
</template>
Advanced Example
<template>
<div>
<input v-model="newTaskTitle" @keyup.enter="addTask" placeholder="Add a new task" />
<ul>
<li v-for="task in filteredTasks" :key="task.id">
<input type="checkbox" v-model="task.completed" />
<span :class="{ completed: task.completed }">{{ task.title }}</span>
<button @click="removeTask(task.id)">Delete</button>
</li>
</ul>
<button @click="showCompleted = !showCompleted">
Show {{ showCompleted ? 'Active' : 'Completed' }} Tasks
</button>
</div>
</template>
<script>
import { ref, computed, watch, onMounted } from 'vue';
export default {
setup() {
const tasks = ref([]);
const newTaskTitle = ref('');
const showCompleted = ref(false);
const filteredTasks = computed(() => {
return tasks.value.filter(task =>
showCompleted.value ? task.completed : !task.completed
);
});
function addTask() {
if (newTaskTitle.value.trim() !== '') {
tasks.value.push({
id: Date.now(),
title: newTaskTitle.value,
completed: false,
});
newTaskTitle.value = '';
}
}
function removeTask(id) {
tasks.value = tasks.value.filter(task => task.id !== id);
}
watch(tasks, (newTasks) => {
console.log('Tasks updated:', newTasks);
}, { deep: true });
onMounted(() => {
console.log('Component is mounted');
});
return { tasks, newTaskTitle, filteredTasks, addTask, removeTask, showCompleted };
}
};
</script>
<style>
.completed {
text-decoration: line-through;
}
</style>
Explanation
Template: Provides an input to add new tasks, a list to display tasks, and a button to toggle between showing completed and active tasks.
Reactive State (
ref
):tasks
,newTaskTitle
, andshowCompleted
are reactive states.tasks
is an array of task objects,newTaskTitle
tracks the input field value, andshowCompleted
toggles the visibility of tasks.Computed Property (
computed
):filteredTasks
is a computed property that returns tasks based on theshowCompleted
state.Methods:
addTask
adds a new task to thetasks
array, andremoveTask
removes a task by itsid
.Watchers (
watch
): A watcher is used to log to the console whenever thetasks
array changes.Lifecycle Hook (
onMounted
): TheonMounted
hook logs a message when the component is mounted to the DOM.
This example is a comprehensive demonstration of various Vue 3 Composition API features, including ref
, and it provides a solid foundation for building more complex Vue applications.
Conclusion
Vue 3's ref
function is a powerful tool in the Vue developer's arsenal. It simplifies the way we handle reactivity, making it easier to manage state and interact with the DOM. As you build Vue applications, ref
will likely become a fundamental part of your development process, helping you write cleaner, more efficient code.
Remember, the key to mastering Vue, or any framework, is practice and exploration. So, experiment with ref
and the Composition API to discover the many creative ways you can enhance your Vue applications.