Implement SVG Hover Color Change Using a Vue Custom Directive
This article explains how to create a reusable Vue custom directive that changes an SVG's fill color on hover, covering simple fill‑only SVGs, dynamic color parameters, and handling more complex SVGs by swapping SVG markup strings.
In frontend development, a common requirement is to change an SVG image's style when the user hovers over it. The traditional approach of using two separate SVG files and toggling their visibility with v-show is cumbersome and hard to maintain.
For simple SVGs whose color can be controlled solely by the fill attribute, you can change the fill value directly instead of duplicating the SVG. The article demonstrates a Vue custom directive that does exactly this.
<template> <div> <button @click="toggleColor">切换svg颜色</button> <svg v-show="isRed" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100"> <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/> </svg> <svg v-show="!isRed" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100"> <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="blue"/> </svg> </div> </template> <script> export default { data() { return { isRed: true }; }, methods: { toggleColor() { this.isRed = !this.isRed; } } }; </script>
Instead of duplicating SVGs, the article introduces a simpler method: apply a custom directive (e.g., v-color='blue' ) to the SVG's parent element, which changes the fill on hover.
Key steps to create the directive:
Create a directive file directives/color.js that defines the directive logic.
Register the directive globally in main.js using app.directive('color', color) .
Use the directive in templates, e.g., <div v-color="'blue'"><svg ...>...</svg></div> .
// directives/color.js const color = { beforeMount(el, binding) { const wrapDom = el; const svg = el.querySelector('svg'); const originColor = svg.style.fill; wrapDom.onmouseenter = function() { svg.style.fill = binding.value; }; wrapDom.onmouseleave = function() { svg.style.fill = originColor; }; } }; export default { install(app) { app.directive('color', color); } };
For more complex SVGs where multiple attributes need to change, the directive can accept an array of SVG strings (normal and hover states) and swap the parent element's innerHTML on mouse events.
// handling complex SVGs const color = { beforeMount(el, binding) { const normalSvg = binding.value[0]; const hoverSvg = binding.value[1]; el.onmouseenter = () => { el.innerHTML = hoverSvg; }; el.onmouseleave = () => { el.innerHTML = normalSvg; }; } }; export default { install(app) { app.directive('color', color); } };
The article concludes that using a Vue custom directive provides a clean, reusable solution for SVG hover effects, whether the SVG is simple (changing fill ) or complex (swapping entire SVG markup).
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.