JAVASCRIPT

Building an Undo/Redo Feature in Vue 3 with `watch`

Implement a robust undo/redo functionality in your Vue 3 applications using the `watch` Composition API to track and manage state changes efficiently.

// UndoRedoEditor.vue
<template>
  <div>
    <textarea v-model="editorContent" rows="10" cols="50"></textarea>
    <div>
      <button @click="undo" :disabled="!canUndo">Undo</button>
      <button @click="redo" :disabled="!canRedo">Redo</button>
    </div>
    <p>Current Content: {{ editorContent }}</p>
    <p>History Length: {{ history.length }}</p>
    <p>Current Index: {{ historyIndex }}</p>
  </div>
</template>

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

const editorContent = ref('Initial content');
const history = ref([]);
const historyIndex = ref(-1);

// Initialize history with the initial content
history.value.push(editorContent.value);
historyIndex.value = 0;

watch(editorContent, (newValue, oldValue) => {
  // If we're not at the end of history (e.g., after an undo),
  // trim future states before adding new one
  if (historyIndex.value < history.value.length - 1) {
    history.value = history.value.slice(0, historyIndex.value + 1);
  }
  history.value.push(newValue);
  historyIndex.value = history.value.length - 1;
}, { deep: true, immediate: false }); // immediate: false to avoid adding initial state twice

const canUndo = computed(() => historyIndex.value > 0);
const canRedo = computed(() => historyIndex.value < history.value.length - 1);

const undo = () => {
  if (canUndo.value) {
    historyIndex.value--;
    editorContent.value = history.value[historyIndex.value];
  }
};

const redo = () => {
  if (canRedo.value) {
    historyIndex.value++;
    editorContent.value = history.value[historyIndex.value];
  }
};
</script>
How it works: This snippet demonstrates how to create a basic undo/redo functionality for a text editor using Vue 3's `watch` API. It maintains a `history` array of content states and a `historyIndex`. When `editorContent` changes, `watch` pushes the new state onto the history, pruning future states if an undo has occurred. `undo` and `redo` functions then navigate through this history, updating `editorContent` and disabling buttons as appropriate.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs