Skip to content

Highlight Directive

The v-highlight directive can be used to highlight text within a block of text. It is useful for highlighting search results.

Usage

The v-highlight directive can be used on any element. It accepts a string or an array of strings as its value. The directive will search the element's text content for the given string(s) and wrap them in a span element with the class v-highlight.

Matched Found:

Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit, quaerat rerum. Beatae quidem, est pariatur, quaerat nobis accusamus odit optio tenetur fugiat laborum asperiores, quod ipsam! Fugit amet totam temporibus.

View Code
vue
<script setup>
import { ref } from "vue";
const search = ref("");
const found = ref(null);
const matchFound = (e) => {
  found.value = e.detail;
};
</script>
<template>
  <div class="bg-zinc-100 dark:bg-zinc-900 p-4 rounded-2xl">
    <div>
      <span class="font-semibold"> Matched Found:</span>
      {{ found }}
    </div>
    <input
      v-model="search"
      class="p-2 border w-full max-w-xs rounded-lg focus:outline-none ring-2 focus:ring-blue-600 focus:border-transparent"
    />
    <p
      v-highlight="search"
      @highlight="matchFound"
      class="text-gray-700 dark:text-gray-300 mt-4"
    >
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit, quaerat
      rerum. Beatae quidem, est pariatur, quaerat nobis accusamus odit optio
      tenetur fugiat laborum asperiores, quod ipsam! Fugit amet totam
      temporibus.
    </p>
  </div>
</template>
<style>
.highlight {
  /* background-color: yellow; */
  @apply bg-yellow-400 dark:bg-yellow-700;
}
</style>

Arguments

The v-highlight directive does not accept any arguments.

Modifiers

The v-highlight takes the following modifier:

ModifierDescription
caseSensitiveThe search will be case sensitive. By default, the search is case insensitive.

Emitting Events

The v-highlight directive emits the following event:

Event NameDescription
highlightIt will emit the length of found records (e)=> e.detail

Source Code

js
export const vHighlight = {
  mounted(el, binding) {
    handleHighlight(el, binding);
  },
  updated(el, binding) {
    handleHighlight(el, binding);
  },
};

function handleHighlight(el, binding) {
  // Get the target text content
  const textContent = el.innerText;

  // Remove existing highlights
  el.innerHTML = textContent;

  // Initialize the count to zero
  let matchCount = 0;

  // Ensure that the binding value is provided and not empty
  if (binding.value) {
    // Get modifiers
    const { caseSensitive } = binding.modifiers;

    // Create a regular expression with modifiers for matching
    const flags = `${caseSensitive ? "" : "i"}g`;
    const regex = new RegExp(escapeRegExp(binding.value), flags);

    // Replace matching words with a span for highlighting
    const highlightedText = el.innerHTML.replace(regex, (match) => {
      matchCount++;
      return `<span class="highlight">${match}</span>`;
    });

    // Set the innerHTML of the element with the highlighted text
    el.innerHTML = highlightedText;
  }

  // Emit custom event to indicate how many matches were found
  // and the text that was searched for
  el.dispatchEvent(
    new CustomEvent("highlight", {
      detail: matchCount,
    })
  );
}

// Function to escape special characters in a string to use in a regular expression
function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}