Chapter 82: Vue v-pre Directive
V-pre
This directive is not something you use every day (unlike v-if, v-for, v-model, v-bind, @click…). It is a very targeted escape hatch that tells Vue:
“Do not compile anything inside this element (or this subtree). Show it exactly as raw text, just like normal HTML — no mustache interpolation, no directives, no reactivity, nothing.”
In other words: Vue skips compilation for that part of the template completely.
1. The Core Idea – When & Why You Use v-pre
You reach for v-pre in these very specific situations:
- You want to literally show mustache syntax{{ }} or Vue directives as plain text (great for documentation, tutorials, code examples)
- You are displaying pre-formatted code snippets that contain Vue-like syntax and you don’t want Vue to try to interpret them
- You have third-party generated HTML that contains curly braces or v- attributes and you want to prevent Vue from touching it
- You are debugging and want to disable reactivity/compilation on a specific part of the template temporarily
Most common real-world use-case in 2026 → Showing Vue code examples inside your own Vue app (blog posts, docs, tutorial pages, GitHub README rendered in-app, etc.)
2. Real, Practical Example – Code Snippet Display
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<template> <div class="docs-page"> <h1>Vue v-pre Directive Example</h1> <p>Normal interpolation:</p> <p>{{ message }}</p> <p>With v-pre → mustache is shown literally:</p> <!-- v-pre here prevents Vue from compiling the content --> <pre v-pre> <code> <!-- This will NOT be compiled --> <p>Hello {{ name }}</p> <button @click="sayHello">Click</button> <div v-if="isVisible">Visible</div> </code> </pre> <p>Another example – raw directive syntax:</p> <div v-pre> This text contains a Vue directive that should stay as text: <input v-model="username" placeholder="Enter name" /> </div> </div> </template> <script setup lang="ts"> import { ref } from 'vue' const message = ref('This is normal reactive text') </script> <style scoped> .docs-page { max-width: 800px; margin: 3rem auto; padding: 2rem; background: white; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.08); } pre { background: #f8fafc; padding: 1.5rem; border-radius: 8px; overflow-x: auto; font-family: 'Consolas', 'Monaco', monospace; font-size: 0.95rem; line-height: 1.5; border: 1px solid #e5e7eb; } code { white-space: pre-wrap; } </style> |
What you see in the browser:
- First <p> → normal reactive text: “This is normal reactive text”
- Second <pre v-pre> → raw text, exactly as written:
text012345678<p>Hello {{ name }}</p><button @click="sayHello">Click</button><div v-if="isVisible">Visible</div>
→ Vue did not try to interpret {{ name }}, @click, or v-if
- Third <div v-pre> → the <input v-model=”username”> is shown as plain text, not turned into a real input field
3. v-pre vs Other “Static” Tools – Quick Comparison
| Directive / Pattern | What it does | Re-renders when data changes? | Compiles directives / mustache? | Use-case summary |
|---|---|---|---|---|
| v-once | Render once, then freeze forever | Never | Yes (first time only) | Static text with initial data |
| v-memo | Skip re-render unless dependencies change | Only if deps change | Yes | Expensive subtree, rare changes |
| v-pre | Never compile — show as raw text | Never | No — skips compilation | Show Vue syntax literally, code blocks |
| Plain {{ }} | Normal reactive rendering | Every time | Yes | Most dynamic content |
4. Quick Summary Table – v-pre in 2026
| Question | Answer / Best Practice |
|---|---|
| What does it do? | Skips Vue compilation for that element + subtree — shows raw text |
| Does it evaluate {{ }} ? | No — mustache stays as literal text |
| Does it process other directives? | No — v-if, v-for, @click, :class etc. are shown as plain text |
| Performance gain? | Small but measurable — skips parsing & reactivity setup for that subtree |
| Still useful in 2026? | Yes — especially in documentation sites, blogs, tutorials, code example components |
| Can be combined with v-if/v-for? | Yes — but v-pre wins → content inside is never compiled |
Pro Tips from Real Projects (Hyderabad 2026)
- Use v-preinside <pre><code> blocks when showing Vue/HTML code examples
- Combine with <template v-pre> when you want to freeze multiple lines without wrapper
- Use it in blog/tutorial components — show Vue directives literally without escaping
- Never use v-pre on anything that should be interactive or reactive — you’ll get raw text instead of working buttons/inputs
- For syntax highlighting → pair v-pre with Prism.js, Highlight.js, or shiki — they work on raw text
- In marketing/landing pages → use v-pre + v-cloak together to prevent any flash of raw {{ }}
Your mini practice task:
- Create a “Vue Code Example” component
- Put some Vue/HTML code inside <pre v-pre><code>…</code></pre>
- Compare with normal {{ }} interpolation → see the difference
- Try adding @click or v-if inside v-pre → see it stays as plain text
Any part confusing? Want full examples for:
- v-pre + syntax highlighter (Prism / shiki) for code blocks?
- v-pre vs v-once vs v-memo full comparison?
- v-pre inside a documentation/toc component?
- Real blog post with Vue examples that never compile accidentally?
Just tell me — we’ll build the next clean code-display component together 🚀
