In Vue 3, what do the v-pre and v-cloak directives do, and why does a build-step SFC app not need v-cloak?
answer
- skip compiling a subtree
- show raw mustaches
- hide until mounted
- no in-DOM template, no flash
basics
~20 sVue's v-pre skips compiling an element and its children, so mustaches render literally; v-cloak stays on an element until its component mounts, letting CSS hide raw in-DOM templates. SFCs are precompiled, so no raw template ever flashes.
solid answer
~40 s`v-pre` tells the compiler to **skip** an element and all its children: mustaches and directives inside are output as plain text and attributes, which is handy for documentation that shows Vue syntax. It takes no expression. `v-cloak` also takes no expression; Vue leaves the attribute on the element until the component instance is **mounted** and then removes it, so a rule like `[v-cloak] { display: none }` hides the "flash of uncompiled template" that occurs when a template is written directly in the page's HTML. The docs say `v-cloak` is only needed in **no-build-step** setups: with SFCs the templates are compiled into render functions ahead of time, and the browser never displays the raw template markup.
go deeper
Know that v-pre shows Vue syntax literally and that v-cloak plus a CSS rule hides uncompiled in-DOM templates.
Explain that v-pre is a compile-time skip while v-cloak is a runtime attribute removed on mount, and why SFCs never flash templates.
Diagnose a blank or flashing first paint correctly: v-cloak only for in-DOM templates, otherwise look at loading or server rendering.
Choose between build-step and no-build-step Vue for a project knowing the trade-offs, including in-DOM template quirks like cloaking.
## Two directives about the template itself Most directives bind data to the DOM. `v-pre` and `v-cloak` are different: they concern the **template** as text, before and during compilation. Neither takes an expression. ## v-pre: skip compilation `v-pre` marks an element whose subtree Vue's compiler must not process. Everything inside is rendered exactly as written: ```vue-html <code v-pre>{{ message }} and v-if="ok" are shown literally</code> ``` Uses: - **Documentation and tutorials** that need to display Vue syntax, such as mustaches, on the page. - Large blocks of static markup that contain characters Vue would otherwise try to interpret. Because the subtree is not compiled, nothing inside it is reactive and no components or directives inside it run. ## v-cloak: hide until mounted When Vue is used **without a build step**, the template is often written directly in the HTML page (an **in-DOM template**) and compiled in the browser at mount time. Until that happens the browser shows the markup as it is, including raw `{{ message }}` text, which briefly flashes on screen. `v-cloak` addresses that: 1. Add `v-cloak` to the element, typically the mount root. 2. Add CSS: `[v-cloak] { display: none; }`. 3. The browser hides the element while it still carries the attribute. 4. When the associated component instance is **mounted**, Vue removes the attribute and the rendered content appears. The CSS rule is yours; Vue only manages the attribute. ## Why SFC apps do not need v-cloak | Setup | Where templates are compiled | Raw template visible? | `v-cloak` useful? | |---|---|---|---| | Single-file components with a build tool | at build time, into render functions | never | no | | In-DOM template with a browser build including the compiler | in the browser, at mount | yes, until mount | yes | With SFCs the page's HTML contains only an empty mount element; the component's markup is produced by JavaScript, so there is no uncompiled template to flash. The docs state plainly that `v-cloak` is only needed in no-build-step setups. A delay before content appears in an SFC app is a loading problem (bundle size, data fetching, or server rendering), not a cloaking one. ## Related distinctions - `v-pre` is **compile-time** and permanent: the subtree is never compiled. - `v-cloak` is **runtime** and temporary: the subtree is compiled and rendered; only visibility is managed until mount. - Rendering something once and then skipping updates is `v-once`, a performance directive, and not the same as `v-pre`. ## Interview angles - "How do you show `{{ }}` literally on a Vue page?" Use `v-pre` on the element, or put the text in a string rendered through interpolation. - "Our SFC app shows a blank screen briefly; should we add `v-cloak`?" No; the fix lies in loading or server rendering. - "Does `v-cloak` hide anything by itself?" No; it needs your CSS rule.
- Does `v-cloak` in Vue 3 hide an element without any CSS?No. Vue only keeps the `v-cloak` attribute on the element until its component mounts and then removes it. Hiding comes from your stylesheet, typically `[v-cloak] { display: none; }`.
- How can a Vue 3 page display the text `{{ message }}` literally?Put `v-pre` on the element so the compiler skips it, or render a string containing the braces through interpolation, which escapes it as ordinary text.
saying these in an interview costs you the question
- v-cloak hides the element on its own without CSS.
- SFC apps need v-cloak to avoid a flash of mustaches.
- v-pre renders once and then skips updates.
- Content inside v-pre stays reactive.