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, andshowCompletedare reactive states.tasksis an array of task objects,newTaskTitletracks the input field value, andshowCompletedtoggles the visibility of tasks.Computed Property (
computed):filteredTasksis a computed property that returns tasks based on theshowCompletedstate.Methods:
addTaskadds a new task to thetasksarray, andremoveTaskremoves a task by itsid.Watchers (
watch): A watcher is used to log to the console whenever thetasksarray changes.Lifecycle Hook (
onMounted): TheonMountedhook 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.