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> )} />
编写完成后,去浏览器预览:
但如果你切换其他类别时,你会发现这时候切换类别不变,因为我们没必要每个列别都去服务器重新请求,而是通过中台得到数据,就可以实现变化。如果你像每次重新请求也很简单,只要使用<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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » P20:前台文章列表页2-根据类别读取文章列表
码云笔记 » P20:前台文章列表页2-根据类别读取文章列表