在网页开发中,运用模板是一个非常重要且高效的概念,它能让你将静态的结构(HTML)和(数据)分离开来,极大地提高开发效率和代码的可维护性。

下面我将用一个清晰、分步的方式,详细解释网页中模板是如何运用的。
核心思想:为什么需要模板?
想象一下你要给100个学生发成绩单,每个学生的姓名和分数都不同。
- 不使用模板(硬编码):你需要复制100份HTML,然后手动修改每一份里的学生姓名和分数,如果发现格式错了,你得改100次,这显然是灾难性的。
- 使用模板:你先制作一个“成绩单模板”,里面留出空白处用于填写姓名和分数,你只需要写一个程序,从数据库里读取100个学生的数据,依次填入这个模板中,最后生成100份完整的成绩单,如果模板格式错了,你只需要改一个地方,所有100份成绩单的格式就都对了。
网页模板就是这个“成绩单模板”,它是一种包含占位符的HTML文件,这些占位符在最终渲染时会被真实的数据替换掉。
模板的核心组成部分
一个典型的模板系统由以下三部分组成:

-
模板文件:
- 这就是HTML骨架。
- 包含特殊的模板语法,用来标记哪里需要被动态内容替换。
<h1>{{ student_name }}</h1>,这里的{{ student_name }}就是一个占位符。
-
数据:
- 这就是你要填入模板的真实内容。
- 通常以数据结构的形式存在,最常见的是JSON对象或JavaScript对象。
{ "student_name": "张三", "score": 95 }。
-
模板引擎:
- 这是“魔法师”,负责将数据“注入”到模板中,并最终生成最终的HTML。
- 它会解析模板文件,找到所有占位符,然后用数据中的相应值进行替换。
- 模板引擎可以是前端的(在浏览器中运行),也可以是后端的(在服务器上运行)。
如何运用:一个分步实例
我们通过一个最简单的例子来走一遍流程:显示一个用户的信息。

第1步:创建模板文件
假设我们有一个名为 user_profile.html 的文件,注意里面的 语法。
user_profile.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">用户资料</title>
</head>
<body>
<h1>欢迎,{{ username }}!</h1>
<p>你的邮箱是:{{ email }}</p>
<p>你的个人简介:</p>
<p>{{ bio }}</p>
</body>
</html>
这里 {{ username }}, {{ email }}, {{ bio }} 就是占位符。
第2步:准备数据
我们有一个JavaScript对象来存储用户数据。
const userData = {
username: "李四",
email: "lisi@example.com",
bio: "我是一名前端开发者,热爱编程和设计。"
};
第3步:选择并使用模板引擎
这里我们介绍两种主流方式:前端渲染和后端渲染。
前端渲染 (Client-Side Rendering)
在这种模式下,浏览器会下载模板和数据,然后在用户的浏览器里将它们合并生成最终的HTML。
常用前端模板引擎:
- Mustache.js / Handlebars.js (经典,语法简单)
- EJS (Embedded JavaScript) (语法更像原生JS)
- Nunjucks (功能更强大,支持模板继承等)
使用 Handlebars.js 的示例:
-
引入库:在你的HTML文件中通过CDN引入Handlebars。
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>
-
准备模板和数据:将
user_profile.html的内容(或其一部分)放在一个<script>标签中,并指定一个类型(如text/x-handlebars-template),数据就是上面的userData对象。<!-- 模板定义 --> <script id="profile-template" type="text/x-handlebars-template"> <h1>欢迎,{{ username }}!</h1> <p>你的邮箱是:{{ email }}</p> <p>你的个人简介:</p> <p>{{ bio }}</p> </script> <!-- 数据 --> <script> const userData = { username: "李四", email: "lisi@example.com", bio: "我是一名前端开发者,热爱编程和设计。" }; </script> -
编译和渲染:使用JavaScript编译模板,并用数据填充它,然后将结果插入到页面中。
<div id="app-container"></div> <script> // 1. 获取模板的HTML内容 const templateSource = document.getElementById("profile-template").innerHTML; // 2. 编译模板,得到一个可重用的模板函数 const template = Handlebars.compile(templateSource); // 3. 用数据渲染模板,生成最终的HTML字符串 const htmlOutput = template(userData); // 4. 将生成的HTML插入到页面中 document.getElementById("app-container").innerHTML = htmlOutput; </script>
结果:当页面加载后,<div id="app-container"> 内部会显示:
<h1>欢迎,李四!</h1> <p>你的邮箱是:lisi@example.com</p> <p>你的个人简介:</p> <p>我是一名前端开发者,热爱编程和设计。</p>
后端渲染 (Server-Side Rendering)
在这种模式下,服务器接收到请求后,会在服务器上完成“模板+数据=HTML”的过程,然后将一个完整的、静态的HTML文件发送给浏览器,这种方式对SEO(搜索引擎优化)更友好。
常用后端模板引擎:
- PHP: 原生PHP标签 (
<?php echo $name; ?>) - Python: Jinja2 (非常流行,语法优雅)
- Node.js: EJS, Pug (原 Jade), Handlebars
- Ruby: ERB
- Java: Thymeleaf, JSP
使用 Node.js + EJS 的示例:
-
环境准备:你需要一个Node.js项目,并安装
ejs。npm init -y npm install ejs express
-
创建模板文件:创建一个
views/user_profile.ejs文件。views/user_profile.ejs<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>用户资料</title> </head> <body> <h1>欢迎,<%= username %>!</h1> <p>你的邮箱是:<%= email %></p> <p>你的个人简介:</p> <p><%= bio %></p> </body> </html>注意:EJS 使用
<%= ... %>来输出变量值。 -
编写服务器代码:在
server.js中设置Express服务器,渲染模板。server.jsconst express = require('express'); const app = express(); const port = 3000; // 设置视图引擎为 EJS app.set('view engine', 'ejs'); // 模拟从数据库获取的数据 const userData = { username: "王五", email: "wangwu@example.com", bio: "我是一名后端工程师。" }; // 定义路由 app.get('/profile', (req, res) => { // res.render() 会自动找到 'views' 文件夹下的 'user_profile.ejs' 文件 // 并将 userData 对象作为数据传递给它 res.render('user_profile', userData); }); app.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); }); -
运行:执行
node server.js,然后在浏览器访问http://localhost:3000/profile。 浏览器收到的最终HTML:<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>用户资料</title> </head> <body> <h1>欢迎,王五!</h1> <p>你的邮箱是:wangwu@example.com</p> <p>你的个人简介:</p> <p>我是一名后端工程师。</p> </body> </html>
现代框架中的模板
现代前端框架(如 React, Vue, Angular)已经将模板的概念内置到了组件中,并且采用了更强大的声明式UI范式。
-
React: 使用 JSX (JavaScript XML),JSX看起来像HTML,但它实际上是JavaScript的语法扩展。
function UserProfile(props) { // props 就是数据 return ( <div> <h1>欢迎,{props.username}!</h1> <p>你的邮箱是:{props.email}</p> </div> ); } // 使用 const userData = { username: "赵六", email: "zhaoliu@example.com" }; ReactDOM.render(<UserProfile {...userData} />, document.getElementById('root'));这里的大括号 就是数据注入的“占位符”。
-
Vue: 使用 模板语法,非常接近原生HTML。
<template id="vue-profile"> <div> <h1>欢迎,{{ username }}!</h1> <p>你的邮箱是:{{ email }}</p> </div> </template> <script> const App = { template: '#vue-profile', data() { return { username: "钱七", email: "qianqi@example.com" }; } }; // ... Vue.createApp(App).mount('#app');Vue的 语法和Handlebars几乎一样。
总结与最佳实践
| 特性 | 前端渲染 | 后端渲染 |
|---|---|---|
| 渲染位置 | 用户浏览器 | 服务器 |
| 初始加载 | 可能较慢(需下载JS和数据) | 通常更快(直接接收完整HTML) |
| SEO友好度 | 较差(搜索引擎可能无法执行JS) | 极佳(搜索引擎拿到的是完整HTML) |
| 交互体验 | 极佳(可快速响应,无需刷新页面) | 较差(交互需要重新请求页面) |
| 主要技术 | React, Vue, Angular, Handlebars | EJS, Jinja2, PHP, Thymeleaf |
如何选择?
- 内容为主、需要SEO:如博客、企业官网、新闻门户。首选后端渲染或SSR (Server-Side Rendering)。
- 交互复杂、类App体验:如社交网络、后台管理系统、在线工具。首选前端渲染或CSR (Client-Side Rendering)。
最佳实践:
- 关注点分离:永远保持HTML模板和业务逻辑/数据的分离,这是模板的核心价值。
- 保持简洁:模板中只应该有展示逻辑,不要放复杂的业务逻辑或数据库操作。
- 可重用性:将通用的UI部分(如页头、页脚、导航栏)抽离成独立的模板片段(或组件),以便在整个项目中复用。
- 安全性:在渲染用户输入的数据时,务必使用模板引擎提供的自动转义功能,以防止XSS(跨站脚本)攻击,现代框架和主流模板引擎默认都会开启此功能。
