'# Layui 2.9.2 列表商品展示页 用模板引擎 laytpl Ajax 读取json 数据 筛选数组 filter css 限制文体显示过长用。。。代替
一、背景与问题
在电商平台或内容管理系统中,商品列表展示是核心功能模块。传统开发模式中,前端需要手动拼接HTML字符串,对于数据量大的场景容易导致代码冗余和维护困难。Layui 2.9.2 提供了 laytpl 模板引擎,结合 Ajax 请求 JSON 数据,能够实现动态数据绑定和条件筛选。
本文将深入探讨以下技术要点:
- laytpl 模板引擎的工作原理
- Ajax 异步加载 JSON 数据的实现
- 数组筛选过滤的实现机制
- CSS 实现文本截断显示的原理
- 大数据量下的性能优化方案
二、基本原理
1. laytpl 模板引擎原理
Layui 的 laytpl 是基于 JavaScript 的模板引擎,其核心原理是通过正则表达式解析模板字符串,将占位符(如 {:title})替换为实际数据。其工作流程如下:
- 编译阶段:将模板字符串转换为可执行函数
- 执行阶段:将数据对象传入函数,生成最终 HTML 字符串
// laytpl 原理示例
const template = '{:title} - {:price}';
const compiled = laytpl(template).render({ title: '商品A', price: '¥199' });
console.log(compiled); // 输出 "商品A - ¥199"2. Ajax 请求原理
Ajax 请求通过 XMLHttpRequest 或 fetch 实现,其核心是建立客户端与服务器的异步通信。对于 JSON 数据的处理,需要特别注意:
- 数据类型校验(Content-Type)
- 错误处理(网络错误/服务器错误)
- 响应数据解析(JSON.parse)
3. 数组筛选过滤原理
数组筛选通常使用 filter() 方法,其核心是遍历数组元素并返回符合条件的元素。在商品列表场景中,常见筛选条件包括:
- 分类过滤(category)
- 价格区间(minPrice/maxPrice)
- 热销排序(isHot)
三、环境准备
1. 基础依赖
<!-- 引入 Layui CSS -->
<link href="https://www.layuiadmin.cn/layui/css/layui.css" rel="stylesheet">
<!-- 引入 Layui JS -->
<script src="https://www.layuiadmin.cn/layui/layui.js"></script>2. 开发环境配置
建议使用以下工具链:
- VS Code(代码编辑)
- Node.js(本地服务器)
- Postman(调试接口)
四、核心实现
1. 模板引擎使用示例
<!-- 模板文件:template.html -->
<div class="layui-row">
{volist name="goods" id="item"}
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">{:item.title}</div>
<div class="layui-card-body">
<p>{:item.description}</p>
<div class="layui-card-footer">价格:{:item.price}</div>
</div>
</div>
</div>
{/volist}
</div>关键点说明:
{volist}是 laytpl 的循环语法name="goods"指定数据源变量名id="item"定义当前项变量名
2. Ajax 数据请求与处理
// 前端 JavaScript
layui.use(['jquery', 'laytpl'], function() {
const $ = layui.jquery;
const laytpl = layui.laytpl;
// 模拟 JSON 数据(实际应通过 Ajax 获取)
const goodsData = [
{ id: 1, title: '商品A', price: '¥199', description: '这是商品A的详细描述,包含多行文本内容。' },
{ id: 2, title: '商品B', price: '¥299', description: '商品B的描述信息,用于展示文本截断效果。' }
];
// 渲染模板
const template = document.getElementById('template').innerHTML;
const render = laytpl(template).render(goodsData);
$('#goodsList').html(render);
});3. 文本截断 CSS 实现
/* 样式文件:style.css */
.goods-description {
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}关键点说明:
white-space: nowrap防止换行overflow: hidden隐藏超出部分text-overflow: ellipsis添加省略号
五、完整案例
1. 项目结构
project/
├── index.html
├── style.css
├── script.js
├── data.json
└── templates/
└── goods.html2. 前端代码
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>商品列表</title>
<link href="layui/css/layui.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="layui-container">
<div id="goodsList"></div>
</div>
<script src="layui/layui.js"></script>
<script src="script.js"></script>
</body>
</html>// script.js
layui.use(['jquery', 'laytpl'], function() {
const $ = layui.jquery;
const laytpl = layui.laytpl;
// 模拟 Ajax 请求
$.ajax({
url: 'data.json',
method: 'GET',
success: function(response) {
const data = JSON.parse(response);
const template = document.getElementById('goodsTemplate').innerHTML;
const render = laytpl(template).render(data);
$('#goodsList').html(render);
},
error: function(xhr, status, error) {
console.error('请求失败:', status, error);
}
});
});// data.json
[
{
"id": 1,
"title": "商品A",
"price": "¥199",
"description": "这是商品A的详细描述,包含多行文本内容。"
},
{
"id": 2,
"title": "商品B",
"price": "¥299",
"description": "商品B的描述信息,用于展示文本截断效果。"
}
]<!-- templates/goods.html -->
<div class="layui-row">
{volist name="goods" id="item"}
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">{:item.title}</div>
<div class="layui-card-body">
<p class="goods-description">{:item.description}</p>
<div class="layui-card-footer">价格:{:item.price}</div>
</div>
</div>
</div>
{/volist}
</div>六、源码解析
1. laytpl 模板引擎解析
// laytpl 源码关键部分
function laytpl(template) {
// 编译模板为函数
return function(data) {
// 执行模板渲染
const result = template.replace(/\{([^\}]+)\}/g, function(match, key) {
return data[key] || '';
});
return result;
};
}2. Ajax 请求处理流程
// $.ajax 源码简化版
$.ajax = function(options) {
const xhr = new XMLHttpRequest();
xhr.open(options.method, options.url, true);
xhr.onload = function() {
if (xhr.status === 200) {
options.success(xhr.responseText);
} else {
options.error(xhr.statusText);
}
};
xhr.onerror = function() {
options.error('网络错误');
};
xhr.send();
};七、进阶使用
1. 动态筛选功能
// 筛选函数
function filterGoods(data, filters) {
return data.filter(item => {
return (
(filters.category === null || item.category === filters.category) &&
(filters.minPrice === null || item.price >= filters.minPrice) &&
(filters.maxPrice === null || item.price <= filters.maxPrice)
);
});
}2. 分页处理
// 分页函数
function paginate(data, pageSize, currentPage) {
const start = (currentPage - 1) * pageSize;
const end = start + pageSize;
return data.slice(start, end);
}3. 排序功能
// 排序函数
function sortGoods(data, sortBy, order) {
return data.sort((a, b) => {
if (a[sortBy] < b[sortBy]) return order === 'asc' ? -1 : 1;
if (a[sortBy] > b[sortBy]) return order === 'asc' ? 1 : -1;
return 0;
});
}八、性能与工程实践
1. 性能优化方案
- 模板预编译:将模板字符串在构建时编译成函数,避免每次请求都重新编译
- 数据懒加载:对于大数据量,采用分页加载策略
- 内存缓存:对高频访问的数据进行缓存
- 减少DOM操作:批量更新DOM元素
2. 安全风险分析
- XSS 攻击:用户输入内容未进行转义
- CSRF 攻击:未对请求进行验证
- 数据泄露:敏感字段未做脱敏处理
// 安全处理示例
function escapeHtml(str) {
return str.replace(/[<>&"']/g, function(match) {
return {
'<': '<',
'>': '>',
'&': '&',
'"': '"',
"'": '''
}[match];
});
}3. 方案比较
| 方案 | 优点 | 缺点 |
|---|---|---|
| laytpl | 语法简洁,易于维护 | 不支持复杂逻辑 |
| Handlebars | 支持更复杂的模板逻辑 | 学习成本较高 |
| Vue.js | 双向绑定和响应式更新 | 需要引入框架 |
九、常见问题与踩坑
1. 常见错误示例
// 错误示例:未正确处理异步请求
layui.use('laytpl', function() {
const laytpl = layui.laytpl;
const template = '{:title}';
const render = laytpl(template).render(data);
$('#goodsList').html(render);
});问题分析:未处理 Ajax 请求的异步性,可能导致 data 为 undefined
2. 错误解决方案
// 正确示例:使用回调处理异步数据
layui.use(['jquery', 'laytpl'], function() {
const $ = layui.jquery;
const laytpl = layui.laytpl;
$.ajax({
url: 'data.json',
method: 'GET',
success: function(response) {
const data = JSON.parse(response);
const template = document.getElementById('goodsTemplate').innerHTML;
const render = laytpl(template).render(data);
$('#goodsList').html(render);
}
});
});3. 其他常见问题
- 模板语法错误:未正确闭合
{volist}标签 - 数据类型不匹配:JSON 字段类型与模板预期不一致
- CSS 样式失效:未正确应用
goods-description类
十、最佳实践
1. 推荐方案
- 模板预编译:在构建阶段将模板文件转换为 JS 变量
- 数据脱敏:对价格、描述等字段进行安全处理
- 分页支持:实现客户端分页,减少数据传输量
- 错误处理:添加详细的错误日志和用户提示
2. 推荐代码组织方式
project/
├── assets/
│ ├── css/
│ └── js/
├── templates/
│ └── goods.html
├── data/
│ └── goods.json
├── index.html
└── script.js3. 推荐工具链
- Webpack:打包资源
- ESLint:代码规范校验
- Postman:接口调试
十一、总结
Layui 的 laytpl 模板引擎为前端开发提供了强大的数据绑定能力,结合 Ajax 技术可以实现动态商品列表展示。本文深入探讨了模板引擎的工作原理、数据处理机制、性能优化方案以及安全注意事项,通过完整案例展示了从数据请求到页面渲染的全过程。
在实际项目中,建议:
- 对于中小型项目,使用 laytpl + Ajax 是高效且优雅的选择
- 对于大型项目,可结合 Vue/React 实现更复杂的交互
- 在涉及敏感数据时,务必进行安全处理和数据脱敏
通过合理使用模板引擎和 Ajax 技术,可以显著提升开发效率和页面性能,同时保持代码的可维护性。