这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
创建组件并配置路由
1、创建 src/views/article/index.vue
2、配置路由
页面布局
其中用到组件:
Form 表单用于筛选面板
Table表格用于数据表格
Card卡片外面的阴影盒子
Breadcrumb 面包屑用于路径导航
<template>
<div class='article-container'>
<el-card class="table-filter">
<div slot="header" class="clearfix">
<!-- 面包屑导航路径 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ name: 'Home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>内容管理</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- 数据筛选面板 -->
<el-form ref="form" :model="form" label-width="60px" size='small'>
<el-form-item label="状态:">
<el-radio-group v-model="form.resource">
<el-radio label="全部"></el-radio>
<el-radio label="草稿"></el-radio>
<el-radio label="待审核"></el-radio>
<el-radio label="审核通过"></el-radio>
<el-radio label="审核失败"></el-radio>
<el-radio label="已删除"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="频道:">
<el-select v-model="form.region" placeholder="请选择频道">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="日期:">
<el-date-picker
v-model="form.value1"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">筛选</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>共找到46151条记录</span>
</div>
<!-- 数据表格 -->
<el-table
:data="tableData"
stripe
style="width: 100%"
class="list-table"
>
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
<el-pagination
background
layout="prev, pager, next"
:total="1000">
</el-pagination>
</el-card>
</div>
</template>
<script>
export default {
name: 'ArticleIndex',
components: {},
props: {},
data () {
return {
form: {
name: '',
region: '',
value1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
},
computed: {},
watch: {},
created () {},
mounted () {},
methods: {}
}
</script>
<style scoped lang="less">
.table-filter{
margin-bottom: 20px;
}
.list-table{
margin-bottom: 20px;
}
</style>
(Form 组件大小可调medium / small / mini)
请求获取文章列表数据
- 首先配置接口(api/article.js)
/**
* 文章相关请求模块
*/
import request from '@/utils/request'
/**
* 获取文章列表
*/
export const getArticles = params => {
return request({
method: 'GET',
url: '/mp/v1_0/articles',
// Body 参数使用 data 设置
// Query 参数使用 params 设置
// Headers 参数使用 headers 设置
params
})
}
- 在组件中接收数据
加载import { getArticles } from '@/api/article'
(1)在created中调用对应的接收数据的函数
(2)在methods里编写接收数据的函数
效果
表格的数据渲染操作
官方文档说明:
当el-table元素中注入data对象数组后,在el-table-column中用prop属性来对应对象中的键名即可填入数据,用label属性来定义表格的列名。可以使用width属性来定义列宽
1.把文章对象进行绑定
- 使用prop属性进行接收(articles里面对应的属性名)
<el-table-column
prop="title"
label="标题"
>
</el-table-column>
- 其中状态需要单独设计 (1)首先使用模板中的scope获取到当前行的数据
(2)data里写一个数组对象articleSatus,分别有对应的索引,状态文字,按钮类型
这里的索引不写也可以 scope.row结果:
{ "id": 1529268877534429200, "title": "打黑除恶123", "status": 2, "cover": { "type": 1, "images": [ "toutiao-img.itheima.net/Fp8x6uoqNJT…" ] }, "pubdate": "2022-05-25 09:11:28" }
即
效果
但是这里还是建议写上,以防止status不是数字处理起来麻烦
- 处理封面,依旧用template的scope进行获取,但是这里封面可以没有,因此要做个判断
没有的话,就用在article下的图片,由于图片大小不好,就可以用background-size和width去调
contain 与 cover 的区别,contain以背景宽(最小边)扩展(会出现长补不满问题),cover以长铺满(导致图片会少一部分)具体参见
数据分页
分页的目的是为了缓解查询数据的压力,提高页面的响应速度,让用户更快的看到页面内容。
假如是固定的数据,例如 10 条,20 条,以后不会增加了。那就没有必要分页,没有意义。
如果是动态产生的数据,例如文章列表,商品列表、评论列表。。。数据量增加的越来越多。100w、1000w、数据量很大响应速度就很慢,数据量很大页面渲染也会变慢,。
所以分页就是用来缓解数据查询和渲染的压力的。
数据库中有 100 条数据:
- 第几页
- 每页大小
后端会从数据库中获取数据,
假设每页10条数据
- 请求第1页数据, 1-10
- 请求第2页数据, 11-20
- 请求第3页数据, 21-30
- ...
然后后端通过接口提供给前端使用。
- page 页码,默认第1页
- per_page 每页大小,默认每页 10 条数据
数据筛选:
- 接口的参数
- 通过表单的交互得到接口参数
- 注册分页组件的
current-change事件
(官方文档的事件)
-
对应的函数
// page=1 默认从第一页开始
由于改变了参数,所以要回调接口函数
补充:分页总页码
- 查看官方文档:
sizes 和 page-sizes 控制
page-size对应每页条数
这里我们需要使他与接口数据绑定
(1)在data中定义:pageSize
(2)per_page = this.pageSize
(3)写对应的事件函数
onSizeChange (perPage) {
this.pageSize = perPage
// 这里由于改变了每页条数对应的per_page,要再次回调接口
this.loadArticles()
}
数据筛选
把视图处理成接口需要的数据提交给后端。
筛选状态
1、在 data 中初始化 status 并传递给请求方法
注:axios 不会发送值为 null、undefined 类型的数据,所以初始化为 null。
2、处理表单绑定获取 status 数据
3、点击查询的时候,调用 loadArticles 方法加载数据
同时函数绑定状态
// 使用两个常量接收,由于只支持驼峰命名要给一个重命名total_count: totalCount
这里会出错
组件默认带了参数,因此我们这里要自己传参数(页数从1开始,传1即可)
筛选频道
一、在下拉列表中展示频道列表
1、在 api/article.js 中封装请求获取文章频道的数据接口
/**
* 获取文章频道
*/
export const getArticleChannels = () => {
return request({
method: 'GET',
url: '/mp/v1_0/channels'
})
}
2、在文章组件中请求获取频道数据
3、将频道数据遍历展示到表单选择器中
二、处理筛选
1、在 data 中初始化数据并传递给请求方法(后端要求传channel_id:频道 id,不传为全部)
2、将数据绑定到选择器上
<el-select v-model="channelId" placeholder="请选择频道"> …………………………………………………………
优化处理: 全部可返回所有文章
图片加载不出来不用自己的判断,以及提供大图预览功能
大图预览(绑的是数组)
:preview-src-list="scope.row.cover.images"
组件自带错误判断