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

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

编写根据类别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 [email protected]/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
1. 本站所有免费资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!
2. 本站不保证所提供下载的免费资源的准确性、安全性和完整性,免费资源仅供下载学习之用!如有链接无法下载、失效,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或技术教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
5. 加入前端开发QQ群:565733884,我们大家一起来交流技术!
码云笔记 » P20:前台文章列表页2-根据类别读取文章列表

发表评论

提供最优质的资源集合

立即查看 了解详情