Working with PrimeVue, the rich UI component library for Vue.js, often requires advanced control and customization. One such need arises when developers want to pass an HTML element through or into a PrimeVue component—whether for custom templates, content projection, slots, or DOM manipulation. In this guide, we explore in-depth techniques to pass HTML elements to PrimeVue components with examples, explanations, and best practices.
Understanding PrimeVue’s Component Architecture
PrimeVue follows the Vue.js component-based model, where each UI element is a reusable component. PrimeVue offers support for slots, props, and directives, which makes it possible to inject custom HTML content or control its rendering behavior.
Using Slots to Pass HTML Elements into PrimeVue Components
Slots are the most native Vue.js method for inserting HTML into a component. PrimeVue components like Dialog
, Card
, Button
, and DataTable
support both default and named slots.
Example: Passing HTML into PrimeVue Dialog
vueCopyEdit<Dialog header="Details" v-model:visible="showDialog">
<template #default>
<div>
<h3>This is a custom heading</h3>
<p>This paragraph is passed into the Dialog via default slot.</p>
</div>
</template>
</Dialog>
- The
template #default
allows us to inject custom HTML inside the dialog. - You can also use
v-html
if rendering dynamic HTML from a string.
Using Named Slots for Structured Content
Many PrimeVue components provide named slots for greater flexibility.
Example: PrimeVue Card Component
vueCopyEdit<Card>
<template #title>
<h2><i class="pi pi-star"></i> Featured Post</h2>
</template>
<template #content>
<p>We are passing HTML here through the content slot.</p>
</template>
<template #footer>
<Button label="Read More" icon="pi pi-arrow-right" />
</template>
</Card>
- We pass custom HTML and even other PrimeVue components inside the Card structure using named slots.
Using v-html
to Inject Raw HTML Elements
If you have HTML in the form of a string (for instance from a CMS), you can use v-html
to render it safely:
vueCopyEdit<Panel header="Dynamic HTML">
<div v-html="htmlString"></div>
</Panel>
⚠️ Use
v-html
with caution to avoid XSS vulnerabilities, especially with user-generated content.
Passing HTML through Props for Custom Render Functions
Some PrimeVue components accept custom renderers via props. This is useful when the component doesn’t have a dedicated slot.
Example: PrimeVue DataTable with Custom Column Template
vueCopyEdit<Column field="status" header="Status">
<template #body="slotProps">
<span :class="`status-badge ${slotProps.data.status}`">
{{ slotProps.data.status }}
</span>
</template>
</Column>
- This
body
slot allows injecting HTML inside table rows. - You can use any HTML structure inside, including conditionals, icons, or dynamic classes.
Dynamic HTML with Custom Directives
You can create custom Vue directives to manipulate HTML passed to PrimeVue components.
vueCopyEditapp.directive('append-html', {
mounted(el, binding) {
el.innerHTML = binding.value;
}
});
vueCopyEdit<Card v-append-html="htmlContent" />
This approach provides full control over rendering, but should be carefully managed.
Combining HTML with PrimeVue Transitions and Animations
PrimeVue components like Dialog
, OverlayPanel
, and Tooltip
support transitions. You can inject HTML that also includes animation or lifecycle events.
vueCopyEdit<Dialog v-model:visible="visible" :modal="true" header="Custom Content">
<template #default>
<transition name="fade">
<div>
<h4>Animated Section</h4>
<p>This HTML will fade in.</p>
</div>
</transition>
</template>
</Dialog>
This enhances the interactivity of passed HTML elements.
Advanced: Using Refs to Pass HTML Elements by Reference
In some scenarios, we may need to pass the actual DOM element to a component—for example, to position tooltips, overlays, or popups.
Example: Pass Element Reference to PrimeVue Tooltip
vueCopyEdit<Button ref="btn" label="Hover me" />
<Tooltip target="btn" content="Tooltip text" />
Or use DOM query with lifecycle hooks:
vueCopyEdit<Tooltip :target="tooltipTarget" content="Hovered info" />
<script setup>
import { ref, onMounted } from 'vue';
const tooltipTarget = ref(null);
onMounted(() => {
tooltipTarget.value = document.querySelector('#target-element');
});
</script>
This technique is helpful for advanced use cases where HTML elements must be accessed directly.
Best Practices for Passing HTML into PrimeVue Components
- Use slots whenever possible – It keeps the structure clean and predictable.
- Avoid
v-html
unless necessary – Use only with sanitized content. - Use scoped slots for dynamic data – Especially useful in
DataTable
,Tree
, andTimeline
. - Leverage Vue directives – Custom directives can enhance flexibility without compromising maintainability.
- Reference elements for overlays – Use
ref
andonMounted
to target exact DOM elements.
Conclusion
Passing HTML elements through PrimeVue components is not only possible—it is highly flexible and powerful when done correctly. Whether through slots, props, custom directives, or element references, developers can inject or render rich HTML content across the PrimeVue UI system. Understanding and using these strategies effectively unlocks the full potential of dynamic user interfaces in Vue.js applications.
For enterprise-grade Vue apps that rely on PrimeVue, injecting custom HTML is a frequent need. Using the techniques outlined above will enable developers to build responsive, customizable, and accessible web applications with precision.