在 Vue 页面中,通过浏览器鼠标右键选择 “查看网页源代码” 看到的是初始化的静态 HTML,而不是渲染后的 HTML ,主要原因如下:
静态 HTML 的加载与显示原理
当浏览器请求一个 Vue 应用时,服务器会先返回一个基础的 HTML 文件,这个文件包含了网页的基本结构,比如<html>、<head>、<body>标签,以及用于挂载 Vue 应用的 DOM 元素(通常是一个带有特定 ID 的<div>,例如<div id="app"></div> ),还会包含对 JavaScript 和 CSS 文件的引用等。浏览器接收到这个 HTML 文件后,会先解析并展示这个静态结构,然后开始加载并执行相关的 JavaScript 代码。
渲染后的 HTML 的生成过程
Vue 应用在加载并执行相关 JavaScript 代码后,会根据组件的定义、数据绑定和指令等,通过模板编译、虚拟 DOM 等技术,在内存中构建虚拟 DOM 树,然后将其渲染成真实的 DOM,并挂载到之前提到的挂载点上。这一系列操作是在浏览器的 JavaScript 运行环境中完成的,属于动态行为。
例如,有一个简单的 Vue 应用代码:
1. 初始 HTML 文件(index.html)
<!DOCTYPE html>
<html>
<head>
<title>Vue App</title>
</head>
<body>
<!-- Vue 应用的挂载点 -->
<div id="app"></div>
<!-- 引入 Vue 3 -->
<script src="https://cdn.jsdelivr.net/npm/vue@3.2.47/dist/vue.global.prod.js"></script>
<!-- 应用代码 -->
<script>
const { createApp } = Vue;
const App = {
data() {
return {
message: 'Hello Vue!',
users: ['Alice', 'Bob', 'Charlie']
}
},
template: `
<div class="container">
<h1>{{ message }}</h1>
<ul>
<li v-for="user in users" :key="user">{{ user }}</li>
</ul>
<button @click="addUser">Add User</button>
</div>
`,
methods: {
addUser() {
this.users.push('New User');
}
}
};
createApp(App).mount('#app');
</script>
</body>
</html>
- 关键点:
<div id="app">是 Vue 应用的挂载点,初始为空。- 页面加载时,浏览器首先解析这个 HTML 文件,执行 JavaScript 代码。
2. Vue 如何动态生成 HTML
const App = {
template: `
<div class="container">
<h1>{{ message }}</h1>
<ul>
<li v-for="user in users" :key="user">{{ user }}</li>
</ul>
<button @click="addUser">Add User</button>
</div>
`,
// ...
};
createApp(App).mount('#app'); // 挂载应用
- 运行流程:
- Vue 解析
template字符串,将其编译为渲染函数(虚拟 DOM 描述)。 - 执行渲染函数,生成虚拟 DOM 树(JavaScript 对象)。
- 通过
mount('#app')将虚拟 DOM 转换为真实 DOM,并插入到#app元素中。
- Vue 解析
3.鼠标右键 → 查看网页源代码
看到的内容:
<!DOCTYPE html>
<html>
<head>
<title>Vue App</title>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue@3.2.47/dist/vue.global.prod.js"></script>
<script>
// 应用代码(完整显示)
</script>
</body>
</html>
原因:右键查看源代码获取的是服务器最初返回的静态 HTML 文件,此时 Vue 尚未执行,#app 还是空的。
4.开发者工具 → Elements 面板
看到的内容:
<body>
<div id="app">
<div class="container">
<h1>Hello Vue!</h1>
<ul>
<li>Alice</li>
<li>Bob</li>
<li>Charlie</li>
</ul>
<button>Add User</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@3.2.47/dist/vue.global.prod.js"></script>
<script>
// 应用代码(完整显示)
</script>
</body>
原因:Elements 面板显示的是当前浏览器渲染的实时 DOM,Vue 已经将组件渲染完成并插入到#app中。
为什么会这样?
- 静态 HTML 与动态渲染的分离
- Vue 的模板(如
template: '<div>{{ message }}</div>')在浏览器中被编译为 JavaScript 代码,执行后才生成真实 DOM。 - 右键查看的是磁盘上的原始 HTML 文件,不包含运行时修改。
- Vue 的模板(如
- 浏览器开发者工具的工作原理
- Elements 面板实时反映 DOM 状态,包括 JavaScript 动态修改的内容。
- 而右键查看源代码是直接读取 HTML 文件,与 DOM 状态无关。
动态渲染:Vue 和 React 都是构建单页应用(SPA)的常用框架,它们的页面内容是通过 JavaScript 在浏览器运行时动态生成并渲染到 DOM 上的。初始加载的 HTML 文件可能只是一个简单的骨架,包含基本的<html>、<head>、<body>结构,以及用于挂载 Vue 或 React 应用的一个空的 DOM 元素(比如<div id="app"></div> ) ,实际的页面内容会在后续由框架代码动态填充。
虚拟 DOM:Vue 和 React 都使用了虚拟 DOM(Virtual DOM)技术。虚拟 DOM 是内存中的一种数据结构,用于高效地更新真实 DOM。框架会根据数据变化计算出虚拟 DOM 的差异,然后一次性更新到真实 DOM 上,这使得最终呈现的 DOM 结构是经过一系列动态操作后的结果。
查看最终渲染的 HTML
- Elements 面板(Chrome、Edge 等):打开浏览器的开发者工具(快捷键通常是 F12),切换到 “Elements” 面板。在这个面板中,你可以看到页面最终渲染后的 HTML 结构。例如,在一个 Vue 应用中,当页面加载完成后,原本空的
#app元素下会出现由 Vue 组件渲染出来的各种 HTML 标签,像<div>、<p>、<button>等,以及对应的属性和样式。 - Inspector 面板(Firefox):在 Firefox 浏览器中,开发者工具的 “Inspector” 面板和 Chrome 等浏览器的 “Elements” 面板类似,同样可以查看页面最终渲染的 HTML 结构。
总结对比表
| 操作 | 看到的内容 | 包含动态内容? | 能否查看 Vue 组件? |
|---|---|---|---|
| 右键 → 查看源代码 | 静态 HTML 文件(含挂载点和脚本) | ❌ | ❌ |
| 开发者工具 → Elements | 实时渲染的 DOM 树 | ✅ | ❌(需通过 Vue Devtools) |
| Vue Devtools | 组件树、状态和事件 | ✅ | ✅ |