P20:前台文章列表页2-根据类别读取文章列表

目录
文章目录隐藏
  1. 编写根据类别 ID 获取文章列表接口
  2. 路由和接口管理文件
  3. 编写前台 UI 界面

现在已经可以进入到文章列表页,但是列表页的内容目前还是静态的。我们的意愿是根据文章类别来展现不同的内容,比如前端教程列表就展示前端相关教程,前端工具列表就展示前端用的工具。要实现这个效果,我们还是需要制作一个接口的。

编写根据类别 ID 获取文章列表接口

打开/service/app/default/home.js,编写对应的接口,因为这里需要转换时间,所以只能使用query这种形式。

// 根据类别 id 获取文章列表
async getListById() {
  const id = this.ctx.params.id;
  const sql = 'SELECT article.id as id,' +
    'article.title as title,' +
    'article.introduce as introduce,' +
    "FROM_UNIXTIME(article.addTime,'%Y-%m-%d %H:%i:%s' ) as addTime," +
    'article.view_count as view_count ,' +
    'type.typeName as typeName ' +
    'FROM article LEFT JOIN type ON article.type_id = type.Id' + 
    'WHERE type_id=' + id;

  const results = await this.app.mysql.query(sql);

  this.ctx.body = {
    data: results,
  };
}

路由和接口管理文件

有了接口后,需要中台为其配置路由,才能让前台可以访问到。

打开/service/router/default.js文件,然后在下方增加代码。

router.get('/default/getListById/:id', controller.default.home.getListById);

这样就配置好了路由,接下里去前台的接口管理文件blog/config/apiUrl.js

let ipUrl = 'http://127.0.0.1:7001/default/' 

let servicePath = {
    getArticleList:ipUrl + 'getArticleList' ,  //  首页文章列表接口
    getArticleById:ipUrl + 'getArticleById/',  // 文章详细页内容接口 ,需要接收参数
    getTypeInfo:ipUrl + 'getTypeInfo', // 文章类别接口
    getListById:ipUrl + 'getListById/', // 根据类别 ID 获得文章列表
}
export default servicePath;

这样就可以在前台使用路径访问到中台提供的数据了。

编写前台 UI 界面

因为要进行Axios请求,所以需要用 import 进行引入,打开blog/pages/list.js引入如下文件。

import React,{useState,useEffect} from 'react'
import axios from 'axios'
import  servicePath  from '../config/apiUrl'
import Link from 'next/link'

引入完成后,可以直接使用getInitialProps从接口中获取数据,代码如下。

MyList.getInitialProps = async (context)=>{
  let id =context.query.id
  const promise = new Promise((resolve)=>{
    axios(servicePath.getListById + id).then(
      (res)=>resolve(res.data)
    )
  })
  return await promise
}

getInitialProps写完后,就可以编写 JSX 部分了,这里主要是循环部分<List>组件的代码。

const [ mylist , setMylist ] = useState(list.data);
<List
  header={<div>最新日志</div>}
  itemLayout="vertical"
  dataSource={mylist}
  renderItem={item => (
    <List.Item>
      <div className="list-title">
        <Link href={{pathname:'/detailed',query:{id:item.id}}}>
          <a>{item.title}</a>
        </Link>
      </div>
      <div className="list-icon">
        <IconText icon={ClockCircleOutlined} text={item.addTime} key="list-vertical-star-o" />
        <IconText icon={VideoCameraOutlined} text={item.typeName} key="list-vertical-like-o" />
        <IconText icon={FireOutlined} text={item.view_count} key="list-vertical-message" />
      </div>
      <div className="list-context">{item.introduce}</div>  
    </List.Item>
  )}
/>

编写完成后,去浏览器预览:

前台文章列表页 2-根据类别读取文章列表

但如果你切换其他类别时,你会发现这时候切换类别不变,因为我们没必要每个列别都去服务器重新请求,而是通过中台得到数据,就可以实现变化。如果你像每次重新请求也很简单,只要使用<Link>标签就可以了。

如果是不请求,直接写一个useEffect就可以解决不刷新的问题。

useEffect(()=>{
  setMylist(list.data)
 })

现在一切就都正常了,可以到浏览器中访问一下。可以实现类别的切换和跳转了。

为了方便大家学习,将本节所有源码附上

import React,{useState,useEffect} from 'react'
import axios from 'axios'
import servicePath from '../config/apiUrl'
import Link from 'next/link'
import Head from 'next/head'
import {Row, Col , List , Breadcrumb, Space } from 'antd'
import {ClockCircleOutlined,VideoCameraOutlined,FireOutlined} from '@ant-design/icons'
import Header from '../components/Header'
import Author from '../components/Author'
import Advert from '../components/Advert'
import Footer from '../components/Footer'

const MyList = (list) => {
  const [ mylist , setMylist ] = useState(list.data);
  useEffect(()=>{
    setMylist(list.data);
  })
  const IconText = ({ icon, text }) => (
    <Space>
      {React.createElement(icon)}
      {text}
    </Space>
  );
  return (
    <div>
      <Head>
        <title>Home</title>
      </Head>
      <Header />
      <Row className="comm-main" type="flex" justify="center">
        <Col className="comm-left" xs={24} sm={24} md={16} lg={18} xl={14}>
          <div>
            <div className="bread-div">
              <Breadcrumb>
                <Breadcrumb.Item><a href="/">首页</a></Breadcrumb.Item>
                <Breadcrumb.Item>前端教程</Breadcrumb.Item>
              </Breadcrumb>
            </div>
            <List
              header={<div>最新日志</div>}
              itemLayout="vertical"
              dataSource={mylist}
              renderItem={item => (
                <List.Item>
                  <div className="list-title">
                    <Link href={{pathname:'/detailed',query:{id:item.id}}}>
                      <a>{item.title}</a>
                    </Link>
                  </div>
                  <div className="list-icon">
                    <IconText icon={ClockCircleOutlined} text={item.addTime} key="list-vertical-star-o" />
                    <IconText icon={VideoCameraOutlined} text={item.typeName} key="list-vertical-like-o" />
                    <IconText icon={FireOutlined} text={item.view_count} key="list-vertical-message" />
                  </div>
                  <div className="list-context">{item.introduce}</div>  
                </List.Item>
              )}
            />
          </div>
        </Col>

        <Col className="comm-right" xs={0} sm={0} md={7} lg={5} xl={4}>
          <Author/>
          <Advert/>
        </Col>
      </Row>
      <Footer/>
    </div>
  )
}

MyList.getInitialProps = async (context)=>{
  let id =context.query.id
  const promise = new Promise((resolve)=>{
    axios(servicePath.getListById + id).then(
      (res)=>{
        resolve(res.data)
      }
    )
  })
  return await promise
}

export default MyList

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » P20:前台文章列表页2-根据类别读取文章列表

发表回复