Vue Custom Directive: v-highlight
This challenge will test your understanding of Vue.js custom directives by creating a reusable directive that visually highlights elements based on user-defined criteria. Custom directives are a powerful way to encapsulate DOM manipulation logic and extend Vue's capabilities.
Problem Description
You are tasked with creating a custom Vue.js directive named v-highlight. This directive should allow users to specify a background color and a text color. When applied to an element, the directive should set the element's backgroundColor and color CSS properties accordingly.
Key Requirements:
- Directive Definition: Create a global custom directive named
v-highlight. - Argument Handling: The directive should accept an optional argument. If no argument is provided, it should default to highlighting with a yellow background and black text.
- Value Handling: The directive should accept a value, which will be an object containing
backgroundColorandtextColorproperties.- If
backgroundColoris provided, it should be applied to the element's background. - If
textColoris provided, it should be applied to the element's text color. - If a property is missing, it should fall back to a default.
- If
- Default Values:
- Default
backgroundColor:yellow - Default
textColor:black
- Default
- DOM Manipulation: The directive should directly manipulate the DOM by setting the
style.backgroundColorandstyle.colorproperties of the bound element.
Expected Behavior:
- When
v-highlightis used without any value, the element should have a yellow background and black text. - When
v-highlight="{ backgroundColor: 'lightblue' }"is used, the element should have a light blue background and black text. - When
v-highlight="{ textColor: 'white' }"is used, the element should have a yellow background and white text. - When
v-highlight="{ backgroundColor: 'green', textColor: 'white' }"is used, the element should have a green background and white text.
Edge Cases:
- Invalid Color Values: The directive should not crash if invalid color strings are provided. For simplicity, assume that if a value is provided for
backgroundColorortextColor, it will be a valid CSS color string (e.g.,'red','#FF0000','rgb(255,0,0)'). - Directive Applied to Non-Element Nodes: While less common, consider how the directive might behave if applied to components or other non-DOM elements (though for this challenge, focusing on DOM elements is sufficient).
Examples
Example 1: Basic usage with defaults
<template>
<div v-highlight>This text will be highlighted with default colors.</div>
</template>
Output: The div element will have style="background-color: yellow; color: black;".
Example 2: Customizing background color
<template>
<p v-highlight="{ backgroundColor: 'lightgreen' }">
This paragraph has a custom background color.
</p>
</template>
Output: The p element will have style="background-color: lightgreen; color: black;".
Example 3: Customizing text color
<template>
<span v-highlight="{ textColor: 'blue' }">
This span has a custom text color.
</span>
</template>
Output: The span element will have style="background-color: yellow; color: blue;".
Example 4: Customizing both background and text color
<template>
<h1 v-highlight="{ backgroundColor: 'purple', textColor: 'white' }">
This heading has both custom colors.
</h1>
</template>
Output: The h1 element will have style="background-color: purple; color: white;".
Constraints
- The directive must be implemented in TypeScript.
- The directive should be registered globally using
app.directive(). - The solution should be compatible with Vue 3.
- Focus on the
mountedandupdatedhooks of the directive lifecycle.
Notes
- You will need to create a Vue application instance and register your custom directive with it.
- The directive's value is an object. You'll need to handle the case where the value is
undefinedor an object with missing properties. - Consider using the
bindingobject within the directive hooks to access the directive's value and argument. - This exercise is about manipulating the DOM directly for educational purposes. In real-world scenarios, you might prefer using CSS classes for more complex styling.