Structuring Vue Directives for Readability and Reusability
Discover best practices for writing and organizing custom directives to enhance code clarity and reusability.
0 likes
26 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." } ] } } ] }