这个问题是 DedeCMS 开发中一个非常经典且常见的需求,默认情况下,{dede:list} 的分页是固定的样式,很多情况下无法满足我们自定义的设计需求。

(图片来源网络,侵删)
核心概念
{dede:list}: 这个标签用于在列表页(如list_article.htm)中调用文章列表,它会循环输出文章数据,并自带一个默认的分页导航。multi属性: 这是{dede:list}标签的一个核心属性,它的作用就是替换掉默认的分页代码,让你可以在模板的任意位置(通常是列表下方)插入自定义的分页 HTML 结构。multi属性的值是一个占位符,它会被 DedeCMS 的解析引擎替换成实际的分页链接。
实现步骤
第 1 步:在列表模板中调用 {dede:list} 并添加 multi 属性
打开你的列表模板文件,通常是 /templets/default/list_article.htm。
在 {dede:list} 标签中,加入 multi='page',这里的 'page' 只是一个自定义的变量名,你也可以叫它 p 或者 fenye,只要在后面的 JS 代码中保持一致即可。
示例代码:
{dede:list pagesize='10' multi='page'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
</li>
{/dede:list}
<!-- 我们使用 {dede:page/} 来接收 multi 属性传递过来的分页数据 -->
<div class="dede_pages">
<ul class="pagelist">
{dede:page/}
</ul>
</div>
代码解释:

(图片来源网络,侵删)
pagesize='10': 设置每页显示 10 条文章。multi='page': 告诉 DedeCMS,不要在列表后面显示默认分页,而是把分页数据存放到一个名为page的变量中。{dede:page/}: 这个标签是关键!它是一个空标签,本身不输出任何内容,它的作用是接收并解析multi属性传递过来的page变量,并将其解析成你指定的 HTML 结构。
第 2 步:编写自定义分页的 CSS 样式
为了让分页看起来美观,你需要为分页的 HTML 结构编写 CSS 样式,DedeCMS 默认会给分页链接加上一些特定的 class,我们可以利用这些 class 来进行样式设计。
常见的 Class 名称:
.pageitem: 每个分页项(如1,2,3,下一页)的容器。.pageinfo: 显示总页数、总条数等信息。.pageen: 英文分页文本,如Total,Pages,Prev,Next。.pagea: 当前页的链接(A 标签)。.thisclass: 当前页所在的分页项的 class。
示例 CSS (可以放在你的 CSS 文件中):
/* 分页容器样式 */
.dede_pages {
text-align: center;
margin: 20px 0;
font-size: 14px;
}
/* 分页列表样式 */
.pagelist {
display: inline-flex; /* 使用 flex 布局,让分页项水平排列 */
list-style: none;
padding: 0;
margin: 0;
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
}
/* 每个分页项的样式 */
.pagelist .pageitem {
padding: 8px 12px;
border-right: 1px solid #ddd;
}
/* 最后一项去掉右边框 */
.pagelist .pageitem:last-child {
border-right: none;
}
/* 分页链接的样式 */
.pagelist .pageitem a {
text-decoration: none;
color: #333;
}
/* 鼠标悬停效果 */
.pagelist .pageitem a:hover {
color: #007bff;
font-weight: bold;
}
/* 当前页的样式 */
.pagelist .pageitem.thisclass {
background-color: #007bff;
color: white;
font-weight: bold;
}
/* 当前页的链接不需要下划线 */
.pagelist .pageitem.thisclass a {
color: white;
text-decoration: none;
}
/* 上一页/下一页禁用状态样式 */
.pagelist .pageitem.disabled a {
color: #ccc;
cursor: not-allowed;
}
第 3 步:使用 JavaScript 实现 AJAX 无刷新分页 (可选但强烈推荐)
这是 multi 属性最强大的应用场景,通过 AJAX,用户点击分页时,页面不会整体刷新,只有列表内容区域会重新加载,极大地提升了用户体验。

(图片来源网络,侵删)
实现思路:
- 修改模板: 将列表部分和分页部分用特定的
div包裹起来,并给它们设置id,方便 JS 选中。 - 引入 JS 库: 使用 jQuery 或其他 JS 库来简化 AJAX 操作。
- 编写 JS 代码: 监听分页链接的点击事件,阻止其默认跳转行为,然后用 AJAX 请求新的列表页内容。
- 处理返回数据: 将 AJAX 返回的新内容,替换掉页面旧的内容。
详细代码示例:
修改 list_article.htm 模板:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">{dede:field.title/}</title>
<!-- 引入 jQuery -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- 引入你的 CSS -->
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>{dede:field.title/}</h1>
<!-- 1. 给列表容器加上 id -->
<div id="list-container">
{dede:list pagesize='10' multi='page'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
</li>
{/dede:list}
</div>
<!-- 2. 给分页容器加上 id -->
<div id="page-container" class="dede_pages">
<ul class="pagelist">
{dede:page/}
</ul>
</div>
<!-- 3. 编写 AJAX 分页的 JS 代码 -->
<script type="text/javascript">
$(function(){
// 监听分页容器的点击事件
$('#page-container').on('click', 'a', function(e){
// 阻止 a 标签的默认跳转行为
e.preventDefault();
// 获取当前点击的链接地址
var url = $(this).attr('href');
// 使用 AJAX 加载新内容
$.ajax({
url: url,
type: 'GET',
dataType: 'html', // 期望返回 HTML 片段
success: function(response){
// 从返回的完整 HTML 中,提取出列表部分和分页部分
var newListContent = $(response).find('#list-container').html();
var newPageContent = $(response).find('#page-container').html();
// 用新内容替换掉页面上旧的内容
$('#list-container').html(newListContent);
$('#page-container').html(newPageContent);
// 滚动到页面顶部,提升用户体验
$('html, body').animate({scrollTop: 0}, 300);
},
error: function(){
alert('加载失败,请稍后再试!');
}
});
});
});
</script>
</body>
</html>
代码解释:
$('#page-container').on('click', 'a', ...):使用事件委托,监听#page-container内部所有a标签的点击,这样做的好处是,即使分页是动态加载进来的,JS 也能正确绑定事件。e.preventDefault():核心!阻止了浏览器默认的页面跳转。$.ajax({...}):标准的 jQuery AJAX 请求。dataType: 'html':告诉 jQuery 服务器返回的是 HTML 代码。$(response).find(...):这是最巧妙的一步。response是服务器返回的整个列表页的 HTML 字符串,我们先用 把它包装成一个 jQuery 对象,然后就可以像操作普通 DOM 一样,用.find()方法从中提取出我们需要的#list-container和#page-container的内容。.html():获取或设置元素的 HTML 内容。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
multi + CSS |
实现简单,无需 JS,对 SEO 友好(真实 URL)。 | 每次点击分页都会刷新整个页面,体验稍差。 | 对页面加载速度不敏感,或追求 SEO 的简单网站。 |
multi + AJAX |
用户体验极佳(无刷新加载),页面响应迅速。 | 实现稍复杂,需要引入 JS,对 SEO 不友好(URL 不变,搜索引擎可能认为只有一页内容)。 | 对用户体验要求高的现代网站,如门户、资讯类网站。 |
最佳实践:
对于大多数现代网站,推荐使用 multi + AJAX 的方式,为了兼顾 SEO,你可以在网站底部提供一个完整的“文章列表”页面链接,供搜索引擎抓取,在 AJAX 分页时,可以尝试使用 HTML5 的 History API 来修改浏览器地址栏的 URL,让用户可以分享特定的分页页面,但这会使实现更加复杂,对于大多数情况,上述的 AJAX 方案已经足够好。
