在 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 | 组件树、状态和事件 | ✅ | ✅ |