Structuring Vue Directives for Readability and Reusability
Discover best practices for writing and organizing custom directives to enhance code clarity and reusability.
0 likes
154 views
Rule Content
{
"title": "Structuring Vue Directives for Readability and Reusability",
"description": "Discover best practices for writing and organizing custom directives to enhance code clarity and reusability.",
"category": "Vue Cursor Rules",
"rules": [
{
"name": "Single Responsibility Principle",
"description": "Ensure each custom directive focuses on a single task to enhance maintainability and reusability.",
"examples": {
"bad": [
{
"code": "app.directive('validateAndStyle', {\n bind(el, binding) {\n // Validation logic\n el.addEventListener('input', () => {\n if (!isValid(el.value)) {\n el.style.borderColor = 'red';\n } else {\n el.style.borderColor = 'green';\n }\n });\n }\n});",
"explanation": "Combining validation and styling responsibilities in a single directive violates the Single Responsibility Principle."
}
],
"good": [
{
"code": "app.directive('validate', {\n bind(el, binding) {\n el.addEventListener('input', () => {\n if (!isValid(el.value)) {\n el.setCustomValidity('Invalid input');\n } else {\n el.setCustomValidity('');\n }\n });\n }\n});\n\napp.directive('style', {\n bind(el, binding) {\n // Default styling\n el.style.borderColor = 'blue';\n }\n});",
"explanation": "Separating validation and styling into distinct directives adheres to the Single Responsibility Principle, making the code more modular and maintainable."
}
]
}
},
{
"name": "Descriptive Naming Conventions",
"description": "Use clear and descriptive names for custom directives to convey their purpose effectively.",
"examples": {
"bad": [
{
"code": "app.directive('myDirective', {\n // Directive logic\n});",
"explanation": "The name 'myDirective' is vague and does not indicate the directive's functionality."
}
],
"good": [
{
"code": "app.directive('tooltip', {\n // Directive logic\n});",
"explanation": "The name 'tooltip' clearly describes the directive's purpose, enhancing code readability."
}
]
}
},
{
"name": "Utilize Lifecycle Hooks Appropriately",
"description": "Implement appropriate lifecycle hooks to manage directive behavior effectively.",
"examples": {
"bad": [
{
"code": "app.directive('focus', {\n bind(el) {\n el.focus();\n }\n});",
"explanation": "Using only the 'bind' hook may not handle dynamic updates or cleanup properly."
}
],
"good": [
{
"code": "app.directive('focus', {\n inserted(el) {\n el.focus();\n },\n update(el, binding) {\n if (binding.value) {\n el.focus();\n }\n },\n unbind(el) {\n // Cleanup logic if necessary\n }\n});",
"explanation": "Utilizing 'inserted', 'update', and 'unbind' hooks ensures proper setup, dynamic updates, and cleanup of the directive."
}
]
}
},
{
"name": "Avoid Hardcoding Values",
"description": "Use binding values to create dynamic and reusable directives instead of hardcoding values.",
"examples": {
"bad": [
{
"code": "app.directive('color', {\n bind(el) {\n el.style.color = 'red';\n }\n});",
"explanation": "Hardcoding the color value limits the directive's reusability."
}
],
"good": [
{
"code": "app.directive('color', {\n bind(el, binding) {\n el.style.color = binding.value || 'black'; // Default color\n }\n});",
"explanation": "Using 'binding.value' allows the directive to dynamically set the color, enhancing reusability."
}
]
}
},
{
"name": "Implement Cleanup Logic",
"description": "Ensure directives include cleanup logic to prevent memory leaks and unintended behavior.",
"examples": {
"bad": [
{
"code": "app.directive('resize', {\n bind(el) {\n const onResize = () => {\n // Resize logic\n };\n window.addEventListener('resize', onResize);\n }\n});",
"explanation": "Failing to remove the event listener can lead to memory leaks."
}
],
"good": [
{
"code": "app.directive('resize', {\n bind(el) {\n const onResize = () => {\n // Resize logic\n };\n window.addEventListener('resize', onResize);\n el._onResize = onResize; // Store reference for cleanup\n },\n unbind(el) {\n window.removeEventListener('resize', el._onResize);\n delete el._onResize;\n }\n});",
"explanation": "Implementing 'unbind' hook to remove the event listener ensures proper cleanup and prevents memory leaks."
}
]
}
}
]
}