On this page
v-if / v-else-if / v-elsev-showv-switch / v-casev-forv-bind / :attrv-htmlv-textv-prev-slot / #slotcomponent :isStripped directivesDirectives
Full reference for all template directives supported by htmlc.
v-if / v-else-if / v-else
Renders the element only when the expression is truthy. Whitespace-only text nodes between branches are ignored.
<p v-if="role === 'admin'">Admin panel</p> <p v-else-if="role === 'editor'">Editor view</p> <p v-else>Read-only view</p>
Works on <template> elements too (renders children only, no wrapper element):
<template v-if="items.length > 0"> <ul> <li v-for="item in items">{{ item }}</li> </ul> </template> <template v-else> <p>No items.</p> </template>
v-show
Adds style="display:none" when the expression is falsy. The element is always rendered (unlike v-if). Merges with any existing style attribute.
<div v-show="isVisible">Visible when isVisible is truthy</div>
v-switch / v-case / v-default
Switch/case conditional (implements Vue RFC #482). Must be on a <template> element. Renders the first matching v-case branch.
<template v-switch="status"> <div v-case="'active'">Active</div> <div v-case="'pending'">Pending approval</div> <div v-default>Unknown status</div> </template>
v-for
Repeats the element for each item in the iterable. Supports arrays, maps, and objects.
<!-- Array --> <li v-for="item in items">{{ item }}</li> <!-- With index --> <li v-for="(item, index) in items">{{ index }}: {{ item }}</li> <!-- Object/map --> <li v-for="(value, key) in obj">{{ key }}: {{ value }}</li> <!-- Range (integer) --> <li v-for="i in 5">{{ i }}</li>
Note: Map iteration order follows Go's reflect.MapKeys() — not insertion order. Sort your maps before passing them if order matters.
v-bind / :attr
Dynamically binds an HTML attribute to an expression. The shorthand is :.
<!-- Long form --> <a v-bind:href="url">Link</a> <!-- Shorthand --> <a :href="url">Link</a> <img :src="imageUrl" :alt="imageAlt" /> <!-- Boolean attributes: rendered only when truthy --> <button :disabled="isLoading">Submit</button> <!-- Class binding --> <div :class="isActive ? 'active' : ''">...</div>
When passing props to a component, :propName evaluates the expression:
<Card :title="post.title" :author="post.author" />
:class — object and array syntax
<!-- Object: keys with truthy values are included --> <div :class="{ active: isActive, disabled: !isEnabled }">...</div> <!-- Array: non-empty string elements are included --> <div :class="['btn', isPrimary ? 'primary' : '']">...</div> <!-- Static class and :class are merged --> <div class="card" :class="{ featured: post.featured }">...</div>
:style — object syntax
<!-- camelCase keys are converted to kebab-case in output --> <p :style="{ fontSize: '14px', backgroundColor: theme.bg }">...</p>
Boolean attributes
When a bound attribute name is a recognised boolean attribute
(disabled, checked, selected,
readonly, required, multiple,
autofocus, open), it is omitted
entirely when the value is falsy, and rendered without a value
when truthy.
<button :disabled="isLoading">Submit</button> <!-- renders as <button> when isLoading is false --> <!-- renders as <button disabled> when isLoading is true -->
v-bind="obj" — attribute spreading
When v-bind is used without an attribute name its value must
evaluate to a map[string]any. Each entry is spread as an HTML
attribute. class and style keys follow the same
merge rules. Boolean attribute semantics apply per key.
<!-- Spread HTMX attributes --> <button v-bind="htmxAttrs">Delete</button> <!-- Spread props into a child component --> <Card v-bind="cardProps" :title="override" />
On child components, explicit :prop bindings take precedence
over keys in the spread map.
v-html
Sets the element's inner HTML to the expression value. The value is not HTML-escaped. Only use with trusted content.
<div v-html="renderedMarkdown"></div>
Warning: Never use v-html with user-supplied data — it can introduce XSS vulnerabilities.
v-text
Sets the element's text content to the expression value. HTML-escaped. Replaces all child nodes.
<span v-text="message"></span> <!-- equivalent to --> <span>{{ message }}</span>
v-pre
Skips all interpolation and directive processing for the element and all
its descendants. Mustache syntax ({{ }}) is emitted literally.
The v-pre attribute itself is stripped from the output.
<!-- This renders literally: {{ raw }} --> <code v-pre>{{ raw }}</code>
Use v-pre to show template syntax as documentation or source
examples without the engine treating it as an expression.
v-slot / #slot
Passes content into a named slot of a child component.
<!-- In Layout.vue --> <header><slot name="header" /></header> <main><slot /></main> <!-- Usage --> <Layout> <template #header> <nav><a href="/">Home</a></nav> </template> <p>Page content goes into the default slot.</p> </Layout>
Scoped slots (slot props):
<!-- In List.vue --> <ul> <li v-for="item in items"> <slot :item="item">{{ item }}</slot> </li> </ul> <!-- Usage --> <List :items="posts"> <template #default="{ item }"> <a :href="item.url">{{ item.title }}</a> </template> </List>
<component :is>
Renders a component whose name is determined at runtime. The :is
expression must evaluate to a non-empty string naming a registered component
or a standard HTML element.
<!-- Resolve from a variable --> <component :is="activeView" /> <!-- Inline string literal --> <component :is="'Card'" :title="pageTitle"> <p>slot content</p> </component> <!-- Switch between components in a loop --> <div v-for="item in items"> <component :is="item.type" :data="item" /> </div>
- All attributes other than
:isare forwarded as props. - Default and named slots work exactly as with static component tags.
-
If the resolved name is a standard HTML element (e.g.
"div"), it is rendered as a plain tag, not looked up in the component registry. :isis required; omitting it is a render error.
Stripped directives
These directives are parsed but produce no output — they are client-side only and have no meaning in a server-side renderer:
v-model— two-way binding@event/v-on:event— event listenersv-once— one-time render optimisation hintv-memo— memoisation hintv-cloak— FOUC prevention