因爲一直在用 vue 寫業務,爲了熟悉下 react 開發模式,因此選擇了 react。數據庫一開始用的是 mongodb,後來換成 mysql 了,一套下來感受 mysql 也挺好上手的。react-router、koa、mysql 都是從0開始接觸開發的,期間遇到過不少問題,印象最深的是 react-router 參考官方文檔配置的,楞是跑不起來,花費了好幾個小時,最後才發現看的文檔是v1.0, 而項目中是v4.3, 好在可參考的資料比較多,問題都迎刃而解了。css
預覽地址前端
web端源碼vue
server端源碼node
喜歡或對你有幫助,歡迎 starmysql
前端react
git clone https://github.com/gzwgq222/blog-admin.git cd blog-admin npm install
localhost:2019
ios
server 端nginx
本地安裝 mysql,新建 dev 數據庫
git
git clone https://github.com/gzwgq222/blog-server.git cd blog-server npm install
前端 react + antd 開發,較爲平緩,在此就再也不敘述。主要記錄下 koa + mysql 相關事宜github
全局安裝 koa-generator
npm install -g koa-generato
建立 node-server 項目
koa node-server
安裝依賴
cd node-server npn install
運行
npm dev
出現 Hello Koa 2! 表示運行成功
先看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:定義對數據庫的查詢方法
以 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 ......
後續會在我的博客中添加關於這次部署文章
初嘗 react + Node,錯誤之處還望斧正,歡迎提 issue