Vue 未编译模板闪现现象解说
一、现象描述
在使用 Vue.js 开发项目时,可能会遇到未编译模板闪现(FOUC,Flash of Uncompiled Content)的问题。具体表现为在页面加载初期,用户会短暂看到未经过 Vue 编译的原始 HTML 模板内容,随后这些内容才被 Vue 渲染成正确的视图。这种现象会给用户带来不好的体验,尤其是在网络较慢或者页面初始加载时间较长的情况下。
二、产生原因
2.1 加载顺序问题
Vue.js 是一个渐进式 JavaScript 框架,它需要在页面加载完成后,通过脚本将 Vue 实例挂载到 DOM 节点上进行编译和渲染。在这个过程中,如果 HTML 页面先于 Vue 脚本加载完成,浏览器会先渲染原始的 HTML 模板内容,直到 Vue 实例完成挂载和编译,才会将模板内容替换为编译后的视图,从而导致未编译模板闪现。
2.2 服务器端渲染问题
在没有使用服务器端渲染(SSR)的情况下,Vue 的渲染过程是在客户端进行的。这意味着在客户端收到 HTML 页面后,需要等待 Vue 脚本加载和执行,期间就会出现短暂的未编译模板显示。
三、解决方案
3.1 使用 v-cloak 指令
- v-cloak 指令可以在 Vue 实例编译完成之前隐藏未编译的模板内容。
- 通过 CSS 选择器 [v-cloak] 将带有 v-cloak 指令的元素隐藏起来,直到 Vue 实例编译完成后,v-cloak 指令会自动移除,元素就会正常显示。
- 使用方法如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue FOUC Example</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
})
</script>
</body>
</html>
3.2 服务器端渲染(SSR)
- 使用服务器端渲染可以在服务器端完成 Vue 组件的渲染,然后将渲染好的 HTML 页面发送到客户端。这样客户端收到的就是已经编译好的 HTML 内容,避免了未编译模板闪现的问题。
- 在实际项目中,可以使用 Vue CLI 创建支持 SSR 的项目,
例如使用 Vue CLI 创建 Nuxt.js 项目,Nuxt.js 是一个基于 Vue.js 的通用应用框架,内置了服务器端渲染功能。 - Vue.js 官方提供了 Vue Server Renderer 来支持服务器端渲染。以下是一个简单的示例:
const Vue = require('vue')
const renderer = require('vue-server-renderer').createRenderer()
const app = new Vue({
template: '<div>{{ message }}</div>',
data: {
message: 'Hello, SSR!'
}
})
renderer.renderToString(app, (err, html) => {
if (err) throw err
console.log(html)
})
3.3 优化脚本加载顺序
确保 Vue 脚本尽快加载和执行。可以将 Vue 脚本放在 HTML 文件的头部,并使用 defer 属性来异步加载脚本,这样可以在不阻塞页面渲染的情况下尽快加载 Vue 脚本。
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js" defer></script>
</head>
四、总结
未编译模板闪现是 Vue 开发中常见的问题,通过使用 v-cloak 指令、服务器端渲染和优化脚本加载顺序等方法,可以有效地解决这个问题,提升用户体验。在实际项目中,需要根据项目的具体情况选择合适的解决方案