本文 AI 產出,尚未審核

Vue3 教學:指令(Directives)— v-cloakv-pre

簡介

在 Vue3 中,指令是與 HTML 標籤 互動的核心機制,允許開發者在模板上掛載特殊行為。除了常見的 v-ifv-showv-model,還有兩個較少被提及、卻在 首次渲染 時發揮關鍵作用的指令:v-cloakv-pre

  • v-cloak 用來 防止閃爍的原始 Mustache 標記{{ }})在 Vue 完成掛載前被瀏覽器渲染。
  • v-pre 則是 告訴 Vue 跳過該區塊的編譯,讓純文字或第三方模板語言可以安全共存。

這兩個指令不會改變資料或 DOM 結構,但在 提升使用者體驗降低不必要的編譯成本 方面相當重要,特別是對於 SEO、SSR 或需要與其他前端框架混用的專案。


核心概念

1. v-cloak:隱藏未編譯的模板

原理

v-cloak 本身不會產生任何功能,它只是一個 CSS 標記。當 Vue 完成編譯並掛載後,會自動移除該屬性。只要在樣式中將 [v-cloak] 設為 display:none,就能避免使用者在頁面加載時看到 {{ message }} 之類的原始字串。

使用方式

<!-- index.html -->
<style>
  [v-cloak] { display: none; }
</style>

<div id="app" v-cloak>
  {{ message }}
</div>
// main.js
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');

重點v-cloak 必須在 Vue 實例掛載之前 生效,因此樣式宣告要放在最上層(如 <head>)或在外部 CSS 中提前載入。


2. v-pre:跳過編譯的區塊

原理

v-pre 告訴 Vue 不對該元素及其子孫執行任何指令解析或 Mustache 替換。這對於以下情況特別有用:

  1. 顯示原始 Mustache 語法(例如教學文件)。
  2. 與其他模板引擎(如 Handlebars、EJS)共存,避免衝突。
  3. 大量靜態內容,可減少 Vue 的編譯成本,提高效能。

使用方式

<!-- 顯示 Mustache 語法的教學範例 -->
<pre v-pre>
  {{ user.name }} // 這裡不會被 Vue 解析
</pre>
<!-- 與 Handlebars 共存 -->
<div id="handlebars-template">
  {{!-- Handlebars 使用 {{}},若不加 v-pre 會被 Vue 攔截 --}}
  {{#if condition}}
    <p>Hello Handlebars!</p>
  {{/if}}
</div>

<div id="app" v-pre>
  <!-- Vue 完全不會編譯這裡的內容 -->
  {{ vueIgnored }}
</div>

3. v-cloakv-pre 的差異

指令 作用 是否編譯子元素 典型使用情境
v-cloak 隱藏未編譯的模板,掛載後自動移除 編譯子元素 防止閃爍的 {{}}、首次渲染時的佈局抖動
v-pre 完全跳過編譯,保留原始文字 不會編譯任何子孫 顯示教學範例、與其他模板引擎共存、提升靜態區塊效能

程式碼範例

範例 1:基本 v-cloak 防止閃爍

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <title>v-cloak 範例</title>
  <style>
    [v-cloak] { display: none; }   /* 隱藏未編譯的內容 */
  </style>
</head>
<body>
  <div id="app" v-cloak>
    <h1>{{ title }}</h1>
    <p>載入中…</p>
  </div>

  <script type="module">
    import { createApp } from 'vue';
    createApp({
      data() {
        return { title: 'Vue3 與 v-cloak' };
      }
    }).mount('#app');
  </script>
</body>
</html>

說明:在 Vue 完成掛載前,[v-cloak] 讓整個區塊隱藏,使用者不會看到 {{ title }}


範例 2:v-pre 用於教學文件

<template>
  <section>
    <h2>Vue Mustache 語法說明</h2>
    <pre v-pre>
      {{ message }}  // 這段文字會原樣顯示,不會被 Vue 解析
    </pre>
  </section>
</template>

<script>
export default {
  data() {
    return { message: 'Hello Vue!' };
  }
};
</script>

說明<pre> 內的 Mustache 會直接呈現在畫面上,適合寫教學手冊或範例程式碼。


範例 3:與 Handlebars 共存的混合模板

<!-- index.html -->
<div id="handlebars-root">
  {{!-- Handlebars 變數 --}}
  {{#each items}}
    <li>{{this}}</li>
  {{/each}}
</div>

<div id="vue-app" v-pre>
  <!-- Vue 完全不會觸碰這裡,避免與 Handlebars 的 {{}} 衝突 -->
  {{ vueIgnored }}
</div>

<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.min.js"></script>
<script src="https://unpkg.com/vue@3"></script>
<script>
  // Handlebars 渲染
  const source = document.getElementById('handlebars-root').innerHTML;
  const template = Handlebars.compile(source);
  const html = template({ items: ['A', 'B', 'C'] });
  document.getElementById('handlebars-root').innerHTML = html;

  // Vue 初始化(不會編譯 v-pre 區塊)
  Vue.createApp({}).mount('#vue-app');
</script>

說明v-pre 確保 Vue 不會把 Handlebars 的 {{}} 當成自己的 Mustache,兩者可以和平共存。


範例 4:大量靜態表格使用 v-pre 提升效能

<table v-pre>
  <thead>
    <tr><th>編號</th><th>說明</th></tr>
  </thead>
  <tbody>
    <!-- 這裡是從後端直接注入的靜態 HTML,無需 Vue 解析 -->
    <tr><td>1</td><td>固定說明文字</td></tr>
    <tr><td>2</td><td>固定說明文字</td></tr>
    <!-- ... 1000 筆資料 -->
  </tbody>
</table>

說明:對於數千筆不會變動的資料表,使用 v-pre 可避免 Vue 逐筆編譯,提高首次渲染速度。


範例 5:結合 v-cloakv-pre 的實務案例

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <title>混合範例</title>
  <style>
    [v-cloak] { visibility: hidden; }   /* 隱藏但保留布局,避免跳動 */
  </style>
</head>
<body>
  <div id="app" v-cloak>
    <h1>{{ pageTitle }}</h1>

    <!-- 教學碼區塊,使用 v-pre -->
    <pre v-pre>
      {{ example }} // 這裡不會被 Vue 解析
    </pre>
  </div>

  <script type="module">
    import { createApp } from 'vue';
    createApp({
      data() {
        return {
          pageTitle: 'Vue3 v-cloak & v-pre 混合使用',
          example: 'Hello World'
        };
      }
    }).mount('#app');
  </script>
</body>
</html>

說明v-cloak 確保整個 #app 在 Vue 完成掛載前保持隱蔽,v-pre 則讓教學區塊保持原樣。兩者同時使用,可在同一頁面中兼顧 避免閃爍保留原始文字


常見陷阱與最佳實踐

陷阱 說明 解決方案 / Best Practice
忘記加入 [v-cloak] CSS v-cloak 只是一個屬性,若沒有相對的樣式,使用者仍會看到 {{}} 在全局樣式或 <head> 中加入 [v-cloak] { display:none; }(或 visibility:hidden
v-pre 用在需要互動的區塊 v-pre 會阻止所有 Vue 解析,導致 v-onv-model 等指令失效。 僅在純展示靜態內容使用;若需要互動,改用普通模板或 v-if 包裹
在 SSR 中使用 v-cloak 伺服器端渲染已經產生完整 HTML,v-cloak 仍會隱藏內容,造成空白。 在 SSR 專案中,可在客戶端掛載前移除 v-cloak,或直接使用 v-if 控制渲染時機
樣式優先級不足 若外部 CSS 或框架(如 Bootstrap)對 [v-cloak] 有更高優先權,隱藏效果會失效。 使用更具體的選擇器或 !important(盡量避免)確保隱藏樣式生效
誤用 v-pre 產生 XSS 跳過編譯意味著 Vue 不會對內容做任何過濾,若直接插入不可信的 HTML,可能造成 XSS。 僅在確保內容安全的情況下使用 v-pre,或搭配 v-html 前先做 sanitization

最佳實踐總結

  1. 全局宣告 [v-cloak],確保所有頁面都有防閃爍保護。
  2. 僅在必要時使用 v-pre,避免過度跳過編譯導致功能缺失。
  3. 配合開發工具(Vue Devtools),檢查 v-cloak 是否已被正確移除。
  4. 在 CI/CD 流程或單元測試中加入檢查,確保不會因遺漏 v-cloak 而產生 UI 問題。

實際應用場景

  1. 多語系網站的 SEO 首頁
    需要在伺服器渲染(SSR)後立即呈現完整內容,避免搜尋引擎抓到 {{}}。在客戶端使用 v-cloak 隱藏過渡階段,確保首次渲染的純文字不被曝光。

  2. 教學平台或文件站
    說明 Vue 語法的教學頁面常會示範 Mustache 語法本身,使用 v-pre 可以直接顯示 {{ variable }} 而不被解析。

  3. 與第三方模板引擎混合
    大型企業系統往往同時使用 Handlebars、Mustache、EJS 等,v-pre 能讓 Vue 與這些引擎共存,避免因指令衝突導致渲染錯誤。

  4. 大量靜態資料的報表
    從後端一次性注入千筆不會變動的表格資料,使用 v-pre 可省去 Vue 的編譯時間,提升頁面載入速度。

  5. 漸進式增強(Progressive Enhancement)
    在僅支援純 HTML 的環境下(如舊版瀏覽器),v-pre 可保證內容仍可閱讀;而在支援 JavaScript 的環境中,透過 v-cloak 隱藏過渡,提供更佳使用者體驗。


總結

v-cloakv-pre 雖然是 Vue3 中相對簡單的兩個指令,卻在 首次渲染的穩定性模板衝突的解決 以及 效能優化 上扮演關鍵角色。

  • v-cloak:配合全局 CSS,防止 Mustache 標記閃爍,適用於所有需要平滑首次載入的 Vue 應用。
  • v-pre:讓 Vue 完全跳過編譯,適合展示教學範例、與其他模板引擎共存或處理大量靜態內容。

在實務開發中,只要遵循正確的使用時機避免過度使用,並配合最佳實踐(如全局樣式、測試驗證),就能讓應用在 使用者體驗效能 上都得到顯著提升。希望本篇教學能幫助你在 Vue3 專案中靈活運用 v-cloakv-pre,打造更穩定、易維護的前端介面。祝開發順利!