因为增删改查都是差不多的代码结构,所以只拿增来讲。查资料的时候发现网上很多的例子比较简单,大部分连回调函数的逻辑都不写,导致我在这踩了很多坑。
1.增
代码结构如下:
controller下的user.js:
async save() {
const {ctx} = this;
const param = ctx.request.body;
let userData = param.userData;
let hasSave = false;
if (userData._id) {
//这是更新的逻辑,笔者搭建这套框架时,还没有实现更新,后来在eggjs的ts版本中实现了,这里就不多说了,可以直接看下面的保存操作。
await ctx.service.user.update(userData).then(res => {
console.log(res);
});
} else {
//这里是保存操作
await ctx.service.user.save(userData).then(res => {
hasSave = res; //返回值告诉前端,保存有没有成功,完善的接口应该还有提示信息字段
console.log(res);
});
}
ctx.body = {
error_code: 1,
success: hasSave,
}
}
service下的user.js:
async save(data) {
/*todo save和基于save的ctx.model.Users.create方法,返回的是promise对象*/
const {ctx} = this;
let result;
await ctx.model.Users.create(data)
.then(res => {
console.log(res);
result = true;
})
.catch(err => {
console.log(err)
result = false;
});
return result;
}
model中的user.js:
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const NewsSchema = new Schema({
name: {type: String},
age: {type: Number},
sex: {
type: String,
required: [true, '请选择性别']
}
});
// var connection=mongoose.createConnection('mongodb://localhost:27017/sys_user_manages')
return mongoose.model('sys_user_manage', NewsSchema,'sys_user_manage');
}
router下的user.js:
module.exports=app=>{
const {router,controller} = app;
router.get('users', '/users/list', controller.users.list);
router.post('users', '/users/list', controller.users.list);
router.post('userSave', '/users/save', controller.users.save);
router.post('userDelete', '/users/delete', controller.users.delete);
// router.get('userSave', '/users/save', controller.users.save);
}
最外层router.js:
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const {router, controller} = app;
router.redirect('/', '/users/list', 302); //这里写了个默认的跳转
//拆分路由,引入各路由模块
require('./router/users')(app); //挂载user的路由
};
笔者在写这个框架时,可能有些不成熟的地方,但是后面改造成ts版本后,就懒得改前面不合理的地方了,不过按照这套代码,是可以实现想要的效果的。
2.删改查
因为已经完成了eggjs的ts版本改造,这套代码已经弃用,所以剩余的删改查就不多说了,如果有实验的小伙伴,记得留意moongoose提供的api的回调函数和返回值类型就可以了。
(我发现midway貌似更适合做项目,但是学习使用eggjs对前端有利无害)
3.跨域问题
如果发现在浏览器地址栏中输入接口后,可以获取数据,但是通过前端调用接口,却得不到结果,那大概率是因为跨域问题,前端请求被拦截。
实际上,前端使用vue的话,基本都是前后端分离的项目,所以跑通接口后,第一件事就是要配置跨域。
egg跨域插件为egg-cors,配置方法npm官网有记载,这里说下注意事项。
一般这种配置项,无脑抄官网记载的代码是行不通的,必须要理解官网教程,然后根据自己的实际情况来写配置。
以跨域为例:
官网的推荐写法可能是:EggAppConfig.cors:{……},也可能是appconfig.cors={}
而我ts版的配置代码结构如下:
import {EggAppConfig, EggAppInfo, PowerPartial} from 'egg';
export default (appInfo: EggAppInfo) => {
const config = {} as PowerPartial<EggAppConfig>;
config.cors = {
origin: '*',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS'
};
const userConfig = {
// myAppName: 'egg',
};
return {
...config as {},
...userConfig
};
}
配置项太多了,只列这几个代表性的,显然按照eggts版推荐的方式,是需要把框架底层的配置挂在到config对象,然后用解构语法,将之暴露出去。
userConfig是我自己的公共配置,可以先用const声明,然后暴露出去。
其他配置文件思路类似。一般使用插件,都需要两个js配置,一个负责引入插件,一个负责配置插件信息。