koa react mysql_记一次 React + Koa + Mysql 构建个人博客

前言

由于一直在用 vue 写业务,为了熟悉下 react 开发模式,所以选择了 react。数据库一开始用的是 mongodb,后来换成 mysql 了,一套下来感觉 mysql 也挺好上手的。react-router、koa、mysql 都是从0开始接触开发的,期间遇到过很多问题,印象最深的是 react-router 参考官方文档配置的,楞是跑不起来,花费了好几个小时,最后才发现看的文档是v1.0, 而项目中是v4.3, 好在可参考的资料比较多,问题都迎刃而解了。

博客介绍

前端项目通过 create-react-app 构建,server端通过 koa-generator 构建

前后端分离,博客页、后台管理都在 blog-admin 里,对含有 /admin 的路由进行登录拦截

前端: react + antd + react-router4 + axios

server端: koa2 + mysql + sequelize

部署:server端 运行在 3000 端口,前端 80 端口,nginx设置代理

喜欢或对你有帮助,欢迎 star

功能

登录

分页

查询

标签列表

分类列表

收藏列表

文章列表

发布文章时间轴

文章访问次数统计

回到顶部

博客适配移动端

后台适配移动端

对文章访问次数进行可视化

留言评论

渲染优化、打包优化

效果

标签

0f6ce858c9fa4b23f115e492da7a2303.png

分类

71cabfcaafa9306fc9c92fcb21df4083.png

收藏

b4281df1d27f313384090dd4a98a9634.png

文章

5a3efd3d94e6f82df492fd4260f12db9.png

编辑

56c7bed34a691fc68e5c99855e5bda06.png

博客页

ae18c07f13092b35a1590fb5b9eee8ac.png

响应式

1a0f975f3fc07cfded1f839591180dd6.png

34b09a1868602c3c7a561e26f7e8588e.png

运行项目

前端

git clone https://github.com/gzwgq222/blog-admin.git

cd blog-admin

npm install

复制代码

localhost:2019

server 端

本地安装 mysql,新建 dev 数据库

git clone https://github.com/gzwgq222/blog-server.git

cd blog-server

npm install

复制代码

server 端

前端 react + antd 开发,较为平缓,在此就不再叙述。主要记录下 koa + mysql 相关事宜

全局安装 koa-generator

npm install -g koa-generato

复制代码创建 node-server 项目

koa node-server

复制代码安装依赖

cd node-server

npn install

复制代码运行

npm dev

复制代码

出现 Hello Koa 2! 表示运行成功61d063513f6c52616aab088336504636.png

先看routes文件

index.js

const router = require('koa-router')()

router.get('/', async (ctx, next) => {

await ctx.render('index', {

title: 'Hello Koa 2!'

})

})

router.get('/string', async (ctx, next) => {

ctx.body = 'koa2 string'

})

router.get('/json', async (ctx, next) => {

ctx.body = {

title: 'koa2 json'

}

})

module.exports = router

复制代码

users.js

const router = require('koa-router')()

router.prefix('/users')

router.get('/', function (ctx, next) {

ctx.body = 'this is a users response!'

})

router.get('/bar', function (ctx, next) {

ctx.body = 'this is a users/bar response'

})

module.exports = router

复制代码

分别访问下列路由

localhost:3000/string

localhost:3000/users

localhost:3000/bar

大概你已经猜到了,koa-router 定义路由访问时返回相应的内容,那我们只需要把相应的 data 返回去就行了,只是我们的数据得从数据库查询出来。

本地安装 mysql

项目安裝 mysql

npm install mysql --save

复制代码项目安裝 sequelize

sequelize 是 ORM node框架,对SQL查询语句的封装,让我们可以用OOP的方式操作数据库

npm install --save sequelize

复制代码新建 sequelize.js,建立连接池

const Sequelize = require('sequelize');

const sequelize = new Sequelize('dev', 'root', '123456', {

host: 'localhost',

dialect: 'mysql',

operatorsAliases: false,

pool: {

max: 5,

min: 0,

acquire: 30000,

idle: 10000

}

})

sequelize

.authenticate()

.then(() => {

console.log('MYSQL 连接成功......');

})

.catch(err => {

console.error('链接失败:', err);

});

// 根据模型自动创建表

sequelize.sync()

module.exports = sequelize

复制代码创建 model、controllers 文件夹 定义model:定义表结构;controller:定义对数据库的查询方法

898cd7117a6ee2731838bc8b42ce1414.png

以 tag.js 为例

model => tag.js

const sequelize = require('../sequelize ')

const Sequelize = require('sequelize')

const moment = require('moment') // 日期处理库

// 定义表结构

const tag = sequelize.define('tag', {

id: {

type: Sequelize.INTEGER(11), // 设置字段类型

primaryKey: true, // 设置为主建

autoIncrement: true // 自增

},

name: {

type: Sequelize.STRING,

unique: { // 唯一

msg: '已添加'

}

},

createdAt: {

type: Sequelize.DATE,

defaultValue: Sequelize.NOW,

get() {

// this.getDataValue 获取当前字段value

return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm')

}

},

updatedAt: {

type: Sequelize.DATE,

defaultValue: Sequelize.NOW,

get() {

return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm')

}

}

},

{

// sequelize会自动使用传入的模型名(define的第一个参数)的复数做为表名 设置true取消默认设置

freezeTableName: true

})

module.exports = tag

复制代码

controller => tag.s 定义了 create、findAll、findAndCountAll、destroy 方法

const Tag = require('../model/tag')

const Op = require('sequelize').Op

const listAll = async (ctx) => {

const data = await Tag.findAll()

ctx.body = {

code: 1000,

data

}

}

const list = async (ctx) => {

const query = ctx.query

const where = {

name: {

[Op.like]: `%${query.name}%`

}

}

const {rows:data, count: total } = await Tag.findAndCountAll({

where,

offset: (+query.pageNo - 1) * +query.pageSize,

limit: +query.pageSize,

order: [

['createdAt', 'DESC']

]

})

ctx.body = {

data,

total,

code: 1000,

desc: 'success'

}

}

const create = async (ctx) => {

const params = ctx.request.body

if (!params.name) {

ctx.body = {

code: 1003,

desc: '标签不能为空'

}

return false

}

try {

await Tag.create(params)

ctx.body = {

code: 1000,

data: '创建成功'

}

}

catch(err) {

const msg = err.errors[0]

ctx.body = {

code: 300,

data: msg.value + msg.message

}

}

}

const destroy = async ctx => {

await Tag.destroy({where: ctx.request.body})

ctx.body = {

code: 1000,

desc: '删除成功'

}

}

module.exports = {

list,

create,

listAll,

destroy

复制代码在 routers 文件夹 index.js 中引入定义好的 tag controller ,定义路由

const router = require('koa-router')()

const Tag = require('../controllers/tag')

// tag

router.get('/tag/list', Tag.list)

router.get('/tag/list/all', Tag.listAll)

router.post('/tag/create', Tag.create)

router.post('/tag/destroy', Tag.destroy)

module.exports = router

/* 如每个 route 是单独的文件,可以使用 router.prefix 定义路由前缀

router.prefix('/tag')

router.get('/list', Tag.list)

router.get('/list/all', Tag.listAll)

router.post('/create', Tag.create)

router.post('/destroy', Tag.destroy)

*/

复制代码

因为 app 中 已经引入 routers 中的 index.js 调用了 app.use了,所以此处不需再引入

在浏览器里输入 localhost:3000/tag/list 就可以看到返回的数据结构了,只不过 data 为空数组,因为我们还没添加进去任何数据

到这里,model 定义表结构、sequelize操作数据库、koa-router 定义路由 这一套流程算是完成了,其他表结构,接口 都是一样定义的

总结

之前没有写过 node server 和 react,算是从零搭建该博客,踩了一些坑,也学到了很多东西,譬如react 开发模式、react-router、sequelize 操作mysql的crud、koa、nginx的配置等等。

麻雀虽小,也是一次完整的前后端开发体验,脱离了浏览器的限制,像海贼王一样,打开了新世界的大门,寻找 onepiece ......

后续会在个人博客中添加关于此次部署文章

Links

初尝 react + Node,错误之处还望斧正,欢迎提 issue

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值