用react+koa+MongoDB开始全栈开发

1,696 阅读3分钟

本文将介绍如何使用react+koa+MongoDB开发一个简单的页面,并写几个简单的接口来实现对数据库的增删改查。

创建数据库

个人比较喜欢用docker来启动MongoDB。
所以先去docker官网下载一个docker。www.docker.com/products/do…
docker启动mongoDb

docker run --name mongo -p 27017:27017 -d mongo:3.4
// —name 指定库的名字,如果不指定会使用一串随机字符串。
// -p 27017:27017 官方的镜像已经暴露了 27017 端口,我们将它映射到主机的端口上。
// -d 在后台运行。
// mongo:3.4 指定镜像版本,默认是 latest 。建议总是自己指定版本。
docker ps
// 查看正在运行的容器

进入mongo shell创建新库

docker exec -it mongo mongo
use newdb
db.user.insert({name: 'Brady'})

创建node后端服务

创建一个my-server文件夹,底下目录结构如下

app.js
使用一些中间件并启动服务监听端口

const Koa = require('koa')
const cors = require('koa-cors')
const app = new Koa()
const router = require('./router')
const bodyParser = require('koa-bodyparser')

app.use(bodyParser()) // 把koa2上下文的formData数据解析到ctx.request.body中
app.use(cors()) // 解决跨域问题
app.use(router.routes()) // 使用路由中间件处理路由
app.listen(3366) // 监听3366端口
console.log('app is stared & listening on port 3366')

router.js
划分路由

const router = require('koa-router')()
const UserController = require('./controller/UserController')

router.get('/user/getUser', UserController.getUser) // 获取用户名字的接口
router.post('/user/updateUser', UserController.updateUser) // 修改用户名字接口

module.exports = router

/controller/UserController.js
编写具体的接口逻辑

const { User } = require("../model/");

class UserController {
    static async getUser(ctx) {
        const { id } = ctx.request.query;
        const list = await User.getUser(id);
        ctx.body = list;
    }
    static async updateUser(ctx) {
        const { name, id } = ctx.request.body;
        const result = await User.update({ _id: id }, { name });
        ctx.body = {
            code: 0,
            message: "success"
        };
    }
}

module.exports = UserController;

/model/index.js
将文件夹中的model导出

const fs = require('fs')
const path = require('path')
// 将文件夹中的model导出
const models = fs.readdirSync(path.resolve(__dirname, './'))
let ret = {}
for (const model of models) {
  if (model === 'index.js' || model === 'ModelBuilder.js') {
    continue
  }
  ret[model.slice(0, model.indexOf('.js'))] = require(`./${model}`)
}
module.exports = ret

/model/ModelBuilder.js
model的构造工厂

const mongoose = require('mongoose')
class ModelBuilder {
  /**
   * 构造model
   *
   * @param.name {String} collection name
   * @param.db {String} db name
   * @param.attributes {Object} 表字段定义
   * @param.statics {Object} 静态方法
   * @param.methods {Object} instance methods
   */
  static build ({name = '', db = 'newdb', attributes = {}, statics = {}, methods = {}}) {
    const schema = new mongoose.Schema(attributes)

    schema.set('timestamps', true)
    schema.set('minimize', false)
    schema.set('collection', name)
    schema.set('strict', false)
    schema.set('id', true)
    schema.set('toObject', {getters: true, virtuals: true, minimize: false, id: true})
    schema.set('toJSON', {getters: true, virtuals: true, minimize: false, id: true})

    schema.statics = statics
    schema.methods = methods

    const connection = mongoose.createConnection('mongodb://localhost:27017/' + db)
    const model = connection.model(name, schema)
    model.ObjectId = mongoose.Types.ObjectId

    return model
  }
}
module.exports = ModelBuilder

/model/User.js
数据库里具体某一张表的数据结构和静态方法定义

const ModelBuilder = require('./ModelBuilder.js')

module.exports = ModelBuilder.build({
  name: 'user',
  attributes: {
    name: {type: String}
  },

  statics: {
    /**
     * 取某个用户
     */
    async getUser (userId) {
      let user = await this.findById(userId)
      if (!user) {
        throw new Error('error')
      }
      return user
    }
  }
})

package.json
项目的依赖和启动项目的命令

{
  "name": "backend",
  "version": "1.0.0",
  "description": "backend",
  "main": "app.js",
  "scripts": {
    "dev": "nodemon -w ./ app.js"
  },
  "keywords": [
    "koa2"
  ],
  "author": "Brady",
  "license": "ISC",
  "dependencies": {
    "koa": "^2.4.1",
    "koa-bodyparser": "^3.2.0",
    "koa-cors": "0.0.16",
    "koa-router": "^7.3.0",
    "mongoose": "^4.13.6",
    "nodemon": "^1.12.1"
  }
}

在项目中打开命令行,输入

npm run dev

然后后端服务就跑起来了

建立前端项目

为了方便,就直接使用react推荐的create-react-app来新建一个react项目
打开命令行

npm i -g create-react-app
create-react-app my-app
cd my-app
npm i
npm start

输入以上命令后浏览器就会出现这样的一个页面了

将app.js修改成

import React, { Component } from "react";
import "./App.css";
import axios from "axios";

class App extends Component {
    constructor() {
        super();
        this.state = {
            name: "",
            value: ""
        };
    }
    componentDidMount() {
        this.getName();
    }
    getName = async () => {
        let { data } = await axios.get(`http://localhost:3366/user/getUser`, {
            params: { id: "5be0eb13b3674cac694c7abf" }
        });
        this.setState({ name: data.name });
    };
    editName = async () => {
        await axios.post(`http://localhost:3366/user/updateUser`, {
            id: "5be0eb13b3674cac694c7abf",
            name: this.state.value
        });
    };
    render() {
        return (
            <div className="App">
                <header className="App-header">
                    <p>hello {this.state.name}</p>
                    <p>
                        修改名字:{" "}
                        <input
                            type="text"
                            value={this.state.value}
                            onChange={e => {
                                this.setState({ value: e.currentTarget.value });
                            }}
                        />
                    </p>
                    <div
                        className="btn"
                        onClick={async () => {
                            await this.editName();
                            this.getName()
                        }}
                    >
                        确定
                    </div>
                </header>
            </div>
        );
    }
}
export default App;

然后在项目中打开命令行

npm i axios

最后就会在浏览器看到

结语

到此为止,已经介绍了如何创建一个网页并实现增、查、改数据库。接下来要做什么功能就可以自由发挥,天马星空了。