IT俱乐部 JavaScript Vue中v-cloak和v-pre指令使用详解

Vue中v-cloak和v-pre指令使用详解

在 Vue.js 中,v-cloakv-pre 是两个比较特殊但非常有用的指令。它们主要用于处理模板编译和显示相关的问题。

一、v-cloak 指令:解决闪烁问题

1. 作用与问题场景

问题:当使用 Vue 管理 DOM 时,在 Vue 实例完全加载并编译模板之前,原始的模板语法(如 {{ }})可能会短暂地显示在页面上,造成内容闪烁。

v-cloak 的作用:防止未编译的 Vue 模板在页面加载时闪烁显示。

2. 基本使用



  
    /* 关键:使用属性选择器隐藏所有带有 v-cloak 的元素 */
    [v-cloak] {
      display: none !important;
    }
    
    /* 或者更具体的选择器 */
    #app[v-cloak] {
      display: none;
    }
  

{{ title }}

{{ message }}

{{ dynamicContent }}
// 模拟网络延迟,更容易看到闪烁效果 setTimeout(() => { new Vue({ el: '#app', data: { title: '欢迎页面', message: 'Hello Vue!', showContent: true, dynamicContent: '这是动态内容' }, mounted() { // Vue 实例挂载完成后,v-cloak 属性会自动移除 console.log('Vue 已加载,v-cloak 已移除'); } }); }, 1000); // 延迟 1 秒加载 Vue

3. 实际应用场景

场景 1:完整的单页应用

{{ footerText }}
/* 防止整个应用闪烁 */ [v-cloak] > * { display: none; }

场景 2:配合骨架屏(Skeleton Screen)

{{ pageTitle }}
{{ content }}
/* 基础隐藏 */ [v-cloak] { opacity: 0; } /* 骨架屏样式 */ .skeleton { /* 骨架屏动画样式 */ } .skeleton-header { width: 100%; height: 60px; background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background-size: 200% 100%; animation: loading 1.5s infinite; } @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } // App.vue 或 main.js new Vue({ el: '#app', data: { loading: true, pageTitle: '', content: '' }, async created() { // 模拟数据加载 try { const data = await this.fetchData(); this.pageTitle = data.title; this.content = data.content; } catch (error) { console.error('加载失败:', error); } finally { this.loading = false; } }, methods: { fetchData() { return new Promise(resolve => { setTimeout(() => { resolve({ title: '页面标题', content: '页面内容...' }); }, 1500); }); } } });

场景 3:多个独立组件

{{ articleTitle }}

/* 可以针对不同组件设置不同的隐藏效果 */ #header[v-cloak] { height: 60px; background: #f5f5f5; } #sidebar[v-cloak] { min-height: 300px; background: #f9f9f9; } #content[v-cloak] { min-height: 500px; background: linear-gradient(180deg, #f8f8f8 0%, #f0f0f0 100%); }

4. 进阶使用技巧

配合 CSS 动画实现平滑过渡

/* 使用 CSS 过渡效果 */
[v-cloak] {
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}

.vue-loaded [v-cloak] {
  opacity: 1;
}

/* 或者使用自定义属性 */
:root {
  --vue-loading: block;
}

[v-cloak] {
  display: var(--vue-loading, none);
}

// 在 Vue 加载完成后添加类名
document.addEventListener('DOMContentLoaded', function() {
  new Vue({
    // ... Vue 配置
  }).$nextTick(() => {
    document.body.classList.add('vue-loaded');
  });
});

服务端渲染(SSR)环境下的优化

服务器渲染的标题

/* SSR 特殊处理 */ [v-cloak] [data-ssr] { display: block; } [v-cloak] [data-client] { display: none; } /* Vue 加载完成后 */ #app:not([v-cloak]) [data-ssr] { display: none; } #app:not([v-cloak]) [data-client] { display: block; }

二、v-pre 指令:跳过编译

1. 作用与使用场景

作用:跳过这个元素和它的子元素的编译过程,保持原始内容。

适用场景

  • 显示原始 Mustache 标签
  • 展示 Vue 模板代码示例
  • 提高大量静态内容的渲染性能

2. 基本用法

{{ 这行文本会原样显示 }}

这个也不会被编译: {{ rawContent }}

{{ compiledContent }}

new Vue({ el: '#app', data: { compiledContent: '这是编译后的内容', rawContent: '原始内容' } });

3. 实际应用场景

场景 1:展示代码示例

Vue 指令示例

模板代码:


<div>
  <p>{{ message }}</p>
  <button @click="handleClick">点击我</button>
  <span v-if="show">条件渲染</span>
</div>
    

运行结果:

{{ message }}


条件渲染

new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
show: true
},
methods: {
handleClick() {
this.show = !this.show;
}
}
});

.code-example {
background: #f5f5f5;
padding: 15px;
border-radius: 5px;
border-left: 4px solid #42b983;
margin-bottom: 20px;
}

.demo {
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}

场景 2:性能优化 – 大量静态内容

{{ article.title }}

作者: {{ article.author }} | 发布时间: {{ article.publishTime }}

在计算机科学中,Vue.js 是一套用于构建用户界面的渐进式框架。

与其他大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。

const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

这是一段引用内容,也会原样显示。

评论 ({{ comments.length }})

{{ comment.user }}:

{{ comment.content }}

new Vue({
el: '#app',
data: {
article: {
title: 'Vue.js 入门指南',
author: '张三',
publishTime: '2024-01-15'
},
comments: [
{ id: 1, user: '李四', content: '很好的文章!' },
{ id: 2, user: '王五', content: '受益匪浅' }
]
}
});

场景 3:与其他模板引擎共存

[[ serverTemplateVariable ]]
{{ item.name }}

4. v-pre 的进阶用法

配合动态属性

{{ rawContent }}
{{ notCompiled }} 正常文本
new Vue({ el: '#app', data: { dynamicClass: 'highlight', dynamicStyle: { color: 'red' } }, methods: { handleClick() { console.log('虽然内容没编译,但事件可以触发'); } } }); .highlight { background-color: yellow; padding: 10px; }

条件性跳过编译

编译跳过模式: {{ rawTemplateSyntax }} 这个 v-if 不会生效
正常编译模式: {{ compiledContent }} 这个 v-if 会生效
new Vue({ el: '#app', data: { skipCompilation: false, compiledContent: '编译后的内容', rawTemplateSyntax: '{{ 原始语法 }}' }, methods: { toggleMode() { this.skipCompilation = !this.skipCompilation; } } });

三、v-cloak 与 v-pre 的比较

特性 v-cloak v-pre
主要目的 防止模板闪烁 跳过编译过程
编译阶段 编译前隐藏,编译后显示 完全跳过编译
性能影响 无性能优化作用 可以提高性能
使用场景 解决显示问题 代码展示、性能优化
CSS 依赖 必须配合 CSS 不需要 CSS
移除时机 Vue 编译后自动移除 一直存在

四、综合应用示例

一个完整的技术文档页面



  Vue 指令文档
    /* v-cloak 样式 */
    [v-cloak] {
      display: none;
    }
    
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      line-height: 1.6;
      color: #333;
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
    }
    
    .container {
      display: grid;
      grid-template-columns: 250px 1fr;
      gap: 30px;
    }
    
    .sidebar {
      position: sticky;
      top: 20px;
      height: fit-content;
    }
    
    .content {
      padding: 20px;
      background: white;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    }
    
    .code-block {
      background: #282c34;
      color: #abb2bf;
      padding: 15px;
      border-radius: 6px;
      overflow-x: auto;
      margin: 20px 0;
    }
    
    .demo-area {
      border: 1px solid #e1e4e8;
      padding: 20px;
      border-radius: 6px;
      margin: 20px 0;
    }
    
    .loading-placeholder {
      background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
      background-size: 200% 100%;
      animation: loading 1.5s infinite;
      height: 100px;
      border-radius: 4px;
    }
    
    @keyframes loading {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }
  

{{ pageTitle }}

{{ section.title }}

{{ section.description }}

{{ section.codeExample }}

演示:

setTimeout(() => {
new Vue({
el: '#app',
data: {
pageTitle: 'Vue 指令详解',
loading: true,
sections: []
},
created() {
// 模拟异步加载数据
this.loadData();
},
methods: {
async loadData() {
// 模拟 API 请求延迟
await new Promise(resolve => setTimeout(resolve, 800));

this.sections = [
{
id: 'v-cloak',
title: 'v-cloak 指令',
description: '用于防止未编译的 Mustache 标签在页面加载时显示。',
codeExample: `

n {{ message }}n

nnn[v-cloak] {n display: none;n}n`,
demo: ‘

编译后的内容会在这里显示


},
{
id: ‘v-pre’,
title: ‘v-pre 指令’,
description: ‘跳过这个元素和它的子元素的编译过程。’,
codeExample: `

n n {{ rawContent }}n 这个不会显示n

`,
demo: ‘{{ 这行代码不会编译 }}’
}
];

this.loading = false;
}
}
});
}, 500);

{{ articleTitle }}

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/js/17030.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部