Build a Vue3 Custom Directive for Image Preview in an Admin Dashboard
This article walks through creating a Vue3 custom directive that leverages Element‑Plus's ElImageViewer to provide image preview functionality in a backend admin system, covering directive registration, event binding, vnode creation, rendering, and cleanup with full code examples.
Review Vue3 directive syntax
The official Vue3 custom directive documentation is referenced, and a simple <div v-color="red">我是红色的文字</div> example demonstrates how a directive can modify the bound element's style.
Create previewImageDirective.ts
Import required types and components, then register a previewImage directive:
import { DirectiveBinding, h, render } from 'vue'
import { ElImageViewer } from 'element-plus'
export default function (app) {
app.directive('previewImage', {
mounted(el: HTMLElement, binding: DirectiveBinding) {
// logic will be added later
}
})
}Explain directive parameters
el: the element the directive is bound to, used for direct DOM manipulation. binding: an object containing value, oldValue, arg, modifiers, instance, and vnode information. value: the value passed to the directive, e.g., v-my-directive="1 + 1" yields 2. oldValue: previous value, available in beforeUpdate and updated hooks. arg: optional argument, e.g., v-my-directive:foo gives "foo". modifiers: object of modifiers, e.g., { foo: true, bar: true } for v-my-directive.foo.bar. instance: the component instance using the directive. vnode: the underlying VNode of the bound element. prevNode: previous render's VNode, usable in beforeUpdate and updated.
Implement the directive logic
Step 1 – bind a click event and change the cursor style:
export default function (app) {
app.directive('previewImage', {
mounted(el: HTMLElement, binding: DirectiveBinding) {
el.addEventListener('click', () => {
el.style.cursor = 'pointer'
})
}
})
}Step 2 – use the h function to create a vnode for ElImageViewer with the image URL and hideOnClickModal option:
vnode = h(ElImageViewer, {
urlList: [binding.value], // image address
hideOnClickModal: true // allow closing by clicking the overlay
})Step 3 – render the vnode into a dynamically created div and append it to document.body:
const previewBox = document.createElement('div')
previewBox.classList.add('preview-box')
render(vnode, previewBox)
document.body.appendChild(previewBox)Step 4 – when the overlay is clicked, remove the created div and clean up listeners:
onClose: () => {
el.removeEventListener('click', () => {})
document.body.removeChild(previewBox)
}Import the directive in main.ts
Finally, import the directive file and invoke it with the Vue app instance:
import imageDirective from 'xxxx/previewImageDirective'
const app = createApp(App)
imageDirective(app)After these steps, any element with v-previewImage="imageUrl" will display a clickable preview that opens the Element‑Plus image viewer and closes cleanly.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IoT Full-Stack Technology
Dedicated to sharing IoT cloud services, embedded systems, and mobile client technology, with no spam ads.
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.
