文章列表模块

90 阅读5分钟

这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

创建组件并配置路由

1、创建 src/views/article/index.vue

2、配置路由

image.png

页面布局

其中用到组件:

Form 表单用于筛选面板

Table表格用于数据表格

DateTimePicker 日期时间选择器日期选择

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)

请求获取文章列表数据

  1. 首先配置接口(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
  })
 }

  1. 在组件中接收数据

加载import { getArticles } from '@/api/article'

(1)在created中调用对应的接收数据的函数

(2)在methods里编写接收数据的函数

image.png

效果

image.png

表格的数据渲染操作

官方文档说明: 当el-table元素中注入data对象数组后,在el-table-column中用prop属性来对应对象中的键名即可填入数据,用label属性来定义表格的列名。可以使用width属性来定义列宽

1.把文章对象进行绑定

image.png

  1. 使用prop属性进行接收(articles里面对应的属性名)
<el-table-column
        prop="title"
        label="标题"
      >
      </el-table-column>
  1. 其中状态需要单独设计 (1)首先使用模板中的scope获取到当前行的数据

image.png (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" }

image.png

效果

image.png

但是这里还是建议写上,以防止status不是数字处理起来麻烦

  1. 处理封面,依旧用template的scope进行获取,但是这里封面可以没有,因此要做个判断

image.png 没有的话,就用在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 条数据

数据筛选:

  • 接口的参数
  • 通过表单的交互得到接口参数
  1. 注册分页组件的 current-change 事件

image.png(官方文档的事件)

image.png

  1. 对应的函数

    // page=1 默认从第一页开始

image.png

由于改变了参数,所以要回调接口函数

补充:分页总页码

  1. 查看官方文档:

image.png

sizes 和 page-sizes 控制image.png

page-size对应每页条数

image.png

这里我们需要使他与接口数据绑定

image.png (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。

image.png

2、处理表单绑定获取 status 数据

image.png

3、点击查询的时候,调用 loadArticles 方法加载数据

同时函数绑定状态

   // 使用两个常量接收,由于只支持驼峰命名要给一个重命名total_count: totalCount

image.png image.png

这里会出错 image.png 组件默认带了参数,因此我们这里要自己传参数(页数从1开始,传1即可)

image.png

筛选频道

一、在下拉列表中展示频道列表

1、在 api/article.js 中封装请求获取文章频道的数据接口

/**
 * 获取文章频道
 */
export const getArticleChannels = () => {
  return request({
    method: 'GET',
    url: '/mp/v1_0/channels'
  })
}

2、在文章组件中请求获取频道数据

image.png

image.png 3、将频道数据遍历展示到表单选择器中

image.png

二、处理筛选

1、在 data 中初始化数据并传递给请求方法(后端要求传channel_id:频道 id,不传为全部)

image.png

2、将数据绑定到选择器上

<el-select v-model="channelId" placeholder="请选择频道"> ………………………………………………………… 优化处理: 全部可返回所有文章

image.png

图片加载不出来不用自己的判断,以及提供大图预览功能

image.png

大图预览(绑的是数组) :preview-src-list="scope.row.cover.images"

组件自带错误判断

效果

image.png