01.文章列表-渲染数据
![](https://i-blog.csdnimg.cn/blog_migrate/38fe0bc10f631c6058d6aa3b5940d8c6.png)
目标
把文章列表数据请求回来, 铺设到页面上
讲解
根据接口文档, 封装接口方法
/**
* 获取文章列表
* @param {*} param0 { pagenum: 当前页码数, pagesize: 当前页条数, cate_id: 文章分类id, state: 文章状态 }
* @returns Promise对象
*/
export const getArticleListAPI = ({ pagenum, pagesize, cate_id, state }) => {
return request({
url: '/my/article/list',
params: {
pagenum,
pagesize,
cate_id,
state
}
})
}
在 data 中定义如下的数据
data() {
return {
// ...其他
artList: [], // 文章的列表数据
total: 0 // 总数据条数
}
}
在 methods 中声明 initArtList函数,请求文章的列表数据:
// 初始化文章列表
async initArtListFn () {
const { data: res } = await getArticleListAPI(this.q)
if (res.code !== 0) return this.$message.error('获取文章列表失败!')
this.artList = res.data
this.total = res.total
}
在 created 中调用步骤2封装的函数:
created() {
// ...其他
// 获取-文章列表
this.initArtListFn()
},
在模板结构中,通过 el-table 组件渲染文章的表格数据:
<!-- 文章表格区域 -->
<el-table :data="artList" style="width: 100%;" border stripe>
<el-table-column label="文章标题" prop="title"></el-table-column>
<el-table-column label="分类" prop="cate_name"></el-table-column>
<el-table-column label="发表时间" prop="pub_date"></el-table-column>
<el-table-column label="状态" prop="state"></el-table-column>
<el-table-column label="操作"></el-table-column>
</el-table>
在发表文章成功后,调用步骤2封装的 initArtList函数:
// 发起请求,发布文章
async postArticle() {
// 创建 FormData 对象
const fd = new FormData()
// 向 FormData 中追加数据
Object.keys(this.pubForm).forEach(key => {
fd.append(key, this.pubForm[key])
})
// 发起请求
const { data: res } = await this.$http.post('/my/article/add', fd)
if (res.code !== 0) return this.$message.error('发布文章失败!')
this.$message.success('发布文章成功!')
// 关闭对话框
this.pubDialogVisible = false
// TODO:刷新文章列表数据
+ this.initArtListFn()
},
小结
文章列表的接口里, 为何需要传这么多的参数?
答案
02 文章列表-格式化时间
目标
把表格里的时间格式化成YYYY-MM-DD HH:mm:ss格式
讲解
安装格式化时间的第三方包 dayjs
yarn add dayjs
在项目入口文件 main.js 中导入并使用 dayjs,定义全局属性, 对应函数
其实也可以在具体定义methods, 也可以定义模块封装导出, 使用的地方引入, 各有各的好处
但是建议公共的工具方法可以挂载到Vue原型上, 组件内直接this.调用访问
// 导入dayjs方法
import dayjs from 'dayjs'
// 定义时间格式化函数
Vue.prototype.$formatDate = (dateObj) => {
return dayjs(dateObj).format('YYYY-MM-DD HH:mm:ss')
}
在 artList.vue组件中,调用全局属性的方法, 对时间进行格式化:
<el-table-column label="发表时间" prop="pub_date">
<template v-slot="{ row }">
<span>{{ $formatDate(row.pub_date) }}</span>
</template>
</el-table-column>
03文章列表-实现分页功能
目标
使用ElementUI的Pagination组件实现分页功能
讲解
在 artList.vue组件中使用 el-pagination组件
<!-- 分页区域 -->
<el-pagination
@size-change="handleSizeChangeFn"
@current-change="handleCurrentChangeFn"
:current-page.sync="q.pagenum"
:page-sizes="[2, 3, 5, 10]"
:page-size.sync="q.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
美化样式:
.el-pagination {
margin-top: 15px;
}
声明 handleSizeChangeFn函数,监听 pageSize 的变化:
// pageSize 发生了变化
handleSizeChangeFn (newSize) {
// 为 pagesize 赋值
this.q.pagesize = newSize
// 默认展示第一页数据
this.q.pagenum = 1
// 重新发起请求
this.initArtListFn()
}
声明 handleCurrentChangeFn函数,监听页码值的变化:
// 页码值发生了变化
handleCurrentChangeFn(newPage) {
// 为页码值赋值
this.q.pagenum = newPage
// 重新发起请求
this.initArtListFn()
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a68a3231a21acb162881d90eaf1310a.png)
04文章列表-实现筛选功能
目标
实现筛选条件切换, 搜索结果更换的效果
讲解
动态为筛选表单中的文章分类下拉菜单,渲染可选项列表
<el-form-item label="文章分类">
<el-select v-model="q.cate_id" placeholder="请选择分类" size="small">
<!-- 循环渲染可选项 -->
<el-option v-for="item in cateList" :key="item.id" :label="item.cate_name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
当用户点击筛选按钮时,调用 initArtList 函数重新发起数据请求:
<el-button type="primary" size="small" @click="initArtListFn">筛选</el-button>
当用户点击重置按钮时,调用 resetList 函数:
<el-button type="info" size="small" @click="resetListFn">重置</el-button>
声明 resetList 函数如下:
// 重置文章的列表数据
resetListFn() {
// 1. 重置查询参数对象
this.q = {
pagenum: 1,
pagesize: 2,
cate_id: '',
state: ''
}
// 2. 重新发起请求
this.initArtListFn()
}
在发布后, 替换调用重置条件方法
// TODO:刷新文章列表数据
this.resetListFn()
05 分页的bug
![](https://i-blog.csdnimg.cn/blog_migrate/b35da026cce96bf6f425a62a2a2d10fb.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b28b63da3bcf6fcfa776f5e5d254fd5b.png)
06 删除最后一页最后一条的bug
![](https://i-blog.csdnimg.cn/blog_migrate/51346ea4afb6be163a4273dbf2265ee0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d5f341ec8d835d568b609ebf933d759b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f5a0ca8a625a6011f17aec0bf222619a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/29db743fcee037101924e92a936fa860.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e8417cd289b3582a7b6a2bd2fcf62ea2.png)