P19:前台文章列表页-接口模块化和读取文章分类
从本文开始,要制作一下文章列表页的前中台结合。由于接口越来越多,现在这样零散的管理非常不利于日后的维护,所以需要单独一个文件,专门用于前台和中台的接口管理。这样在以后部署和更换服务器时都非常简单。
编写统一中台 API 配置文件
在blog的根目录下,新建一个config文件夹,然后在文件夹下建立一个apiUrl.js文件,写入下面的代码。
let ipUrl = 'http://127.0.0.1:7001/default/'
let servicePath = {
getArticleList:ipUrl + 'getArticleList' , // 首页文章列表接口
getArticleById:ipUrl + 'getArticleById/', // 文章详细页内容接口 ,需要接收参数
}
export default servicePath;
完成后,可以去pages/index.js文件中,修改以前的接口路由,在修改前,需要先进行引入。
import servicePath from '../config/apiUrl'
引入后,找到getInitialProps方法直接进行更换
Home.getInitialProps = async () => {
const promise = new Promise((resolve) => {
axios(servicePath.getArticleList).then(
(res) => {
resolve(res.data)
}
)
})
return await promise
}
首页更换完成,再去pages/detailed.js(详细页)文件中进行更换。
//记得要先进行引入
import servicePath from '../config/apiUrl'
//引入后进行修改
Detailed.getInitialProps = async(context)=>{
let id =context.query.id
const promise = new Promise((resolve)=>{
axios(servicePath.getArticleById+id).then(
(res)=>{
resolve(res.data.data[0])
}
)
})
return await promise
}
这样我们就形成了一个统一的接口管理文件,以后在维护上会方便很多。
修改首页接口 读取文章类别信息
我们希望每个页面只读取一次接口,然后服务端渲染好后展示给我们,这时候就需要在首页的getArticleList接口中进行修改了。
文件位置/service/app/default/home.js
修改的代码如下:
// 得到类别名称和编号
async getTypeInfo() {
const result = await this.app.mysql.select('type');
this.ctx.body = { data: result };
}
接口写好之后,就需要我们到服务端配置路由service/app/router/default.js
'use strict';
module.exports = app => {
const { router, controller } = app;
router.get('/default/index', controller.default.home.index);
router.get('/default/getArticleList', controller.default.home.getArticleList);
router.get('/default/getArticleById/:id', controller.default.home.getArticleById);
router.get('/default/getTypeInfo', controller.default.home.getTypeInfo);
};
修改数据库
因为我们设计的是有 Icon 的,但是这个数据缺少一个图标选项,现在把图标也存入数据库中。关于图标这一块我使用的是 iconfont 自定义图标,官方文档
我们打开 mysql 的管理,然后在里边加入icon字段。
- 前端教程 字段为
iconclass-9 - 前端工具 字段为
icontoolset - 随笔 字段为
iconnote
这时候我们就有了图标字段并且有了值,再次修改<Header>组件的代码,加入图标的部分,并且把博客首页也加上去。
修改 Header 组件
以前我们的 Header 组件是静态写死的,现在我们需要利用useEffect()方法来从接口中获取动态数据。
需要先引入useState和useEffect,然后由于还要进行跳转,所以还要引入Router和Link,由于还要访问接口,所以还要引入axios和servicePath。
import React ,{useState,useEffect} from 'react'
import Router from 'next/router'
import Link from 'next/link'
import axios from 'axios'
import servicePath from '../config/apiUrl'
引入后用useState声明navArray和使用useEffect()获取远程数据
useEffect(()=>{
const fetchDate = async () => {
const result = await axios(servicePath.getTypeInfo).then(
(res) => {
return res.data.data
}
)
setNavArray(result);
}
fetchDate()
},[]);
useEffect()写完后,可以获得博客的分类信息了,要想让分类信息可以跳转,可以写一个方法handleClick。
//跳转到列表页
const handleClick = (e) => {
if (e.key == 0) {
Router.push('/index');
} else {
Router.push('/list?id='+e.key)
}
}
这些都准备好以后,就可以写我们的 JSX 语法,修改<Menu>组件部分了,代码如下:
<Col className="memu-div" xs={0} sm={0} md={14} lg={8} xl={6}>
<Menu mode="horizontal" onClick={handleClick}>
<Menu.Item key="0">
<IconFont type="iconhome" />
首页
</Menu.Item>
{
navArray.map((item)=>{
return (
<Menu.Item key={item.Id}>
<IconFont type={item.icon} />
{item.typeName}
</Menu.Item>
)
})
}
</Menu>
</Col>
最后为了方便大家学习,这里给出全部的Header.js代码。
import React ,{useState,useEffect} from 'react'
import Router from 'next/router'
import Link from 'next/link'
import axios from 'axios'
import servicePath from '../config/apiUrl'
import {Row, Col, Menu} from 'antd'
import {createFromIconfontCN} from '@ant-design/icons'
const Header = () => {
const [navArray, setNavArray] = useState([]);
useEffect(()=>{
const fetchDate = async () => {
const result = await axios(servicePath.getTypeInfo).then(
(res) => {
return res.data.data
}
)
setNavArray(result);
}
fetchDate()
},[]);
const handleClick = (e) => {
if (e.key == 0) {
Router.push('/index');
} else {
Router.push('/list?id='+e.key)
}
}
const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_2253148_geubuprv3qb.js',
});
return (
<div className="header">
<Row type="flex" justify="center">
<Col xs={24} sm={24} md={10} lg={15} xl={12}>
<span className="header-logo">
<Link href={{pathname:'/index'}}>
<a> 码云笔记</a>
</Link>
</span>
<span className="header-txt">专注前端开发,实战技巧分享。</span>
</Col>
<Col className="memu-div" xs={0} sm={0} md={14} lg={8} xl={6}>
<Menu mode="horizontal" onClick={handleClick}>
<Menu.Item key="0">
<IconFont type="iconhome" />
首页
</Menu.Item>
{
navArray.map((item)=>{
return (
<Menu.Item key={item.Id}>
<IconFont type={item.icon} />
{item.typeName}
</Menu.Item>
)
})
}
</Menu>
</Col>
</Row>
</div>
)
}
export default Header
打开浏览器看一下效果:

以上关于P19:前台文章列表页-接口模块化和读取文章分类的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » P19:前台文章列表页-接口模块化和读取文章分类
微信
支付宝