Hone logo
Hone
Problems

Vue Directive Modifiers: Building Reusable Behavior

Vue's custom directives offer a powerful way to encapsulate DOM manipulation logic. While basic directives are useful, modifiers allow for greater flexibility and reusability by enabling users to conditionally alter a directive's behavior. This challenge focuses on creating a custom directive with modifiers to demonstrate how to pass and interpret configuration options directly on the directive binding.

Problem Description

Your task is to create a Vue 3 custom directive named v-highlight. This directive should allow users to highlight an HTML element's background color. Furthermore, it should support two modifiers:

  • .hover: The highlighting should only be active when the user hovers over the element.
  • .once: The highlighting should be applied only the first time the element is mounted and then removed.

You will need to implement the directive's logic to handle these modifiers and apply the appropriate styling.

Key Requirements:

  1. Basic Highlighting: The directive should accept an optional argument representing the highlight color. If no color is provided, it should default to yellow.
  2. .hover Modifier: When the .hover modifier is present, the element should only be highlighted when the mouse pointer is over it. The highlighting should be removed when the mouse leaves.
  3. .once Modifier: When the .once modifier is present, the highlighting should be applied once on mount and then removed. This modifier should work independently of the .hover modifier.
  4. Combining Modifiers: The directive should gracefully handle scenarios where both .hover and .once modifiers are used together. In this case, the highlighting should apply on hover, but only the first time the hover event occurs. After the first hover, the highlighting should no longer be applied, even on subsequent hovers.
  5. TypeScript: Implement the directive logic using TypeScript.

Expected Behavior:

  • v-highlight: Highlights the element with yellow background.
  • v-highlight="'red'": Highlights the element with a red background.
  • v-highlight.hover: Highlights the element with yellow background on hover.
  • v-highlight="'blue'.hover": Highlights the element with a blue background on hover.
  • v-highlight.once: Highlights the element with yellow background once on mount, then removes it.
  • v-highlight="'green'.once": Highlights the element with a green background once on mount, then removes it.
  • v-highlight.hover.once: Highlights the element with yellow background on the first hover, then removes it permanently.
  • v-highlight="'purple'.hover.once": Highlights the element with a purple background on the first hover, then removes it permanently.

Edge Cases:

  • What happens if a color value is provided but is not a valid CSS color string? (For this challenge, assume valid color strings or fall back to the default if invalid, though a robust solution might throw an error).
  • How does the directive behave if it's applied to an element that doesn't have a background color initially? (The directive should apply a background color directly).

Examples

Example 1:

<template>
  <div v-highlight="'lightblue'">This div will be permanently highlighted lightblue.</div>
</template>

Output: The div will have a backgroundColor of lightblue. Explanation: The directive v-highlight is used with a string argument specifying the color.

Example 2:

<template>
  <p v-highlight.hover>Hover over me to see a yellow highlight.</p>
</template>

Output: The paragraph will have a yellow background when the mouse is hovering over it. Explanation: The .hover modifier is used, so the highlighting is applied only during hover. No color argument is provided, so the default yellow is used.

Example 3:

<template>
  <span v-highlight="'orange'.hover.once">First hover triggers orange highlight, then it's gone.</span>
</template>

Output: When the user first hovers over the span, it will turn orange. After the first hover, it will revert to its original background and will not highlight again on subsequent hovers. Explanation: Both .hover and .once modifiers are used with a specific color. The .once modifier ensures the highlighting effect is temporary after the initial hover.

Constraints

  • Vue version: Vue 3
  • Language: TypeScript
  • The directive should not rely on any external libraries beyond Vue.
  • The directive should be efficient and avoid unnecessary DOM manipulations.

Notes

  • You'll need to define the custom directive using app.directive() in your Vue application setup.
  • Pay attention to the binding object passed to the directive hooks, specifically binding.value (for the color) and binding.modifiers (for flags like hover and once).
  • Consider using el.style.backgroundColor for direct DOM manipulation.
  • For the .hover modifier, you'll need to attach and remove event listeners for mouseenter and mouseleave. Remember to clean up these listeners when the element is unmounted.
  • For the .once modifier, you'll need to track whether the "once" action has already occurred.
  • Think about the order of operations when both .hover and .once are present. The .once condition should gate the application of the highlight, even if it's triggered by a hover.
Loading editor...
typescript