egg.js学习笔记
官网
- https://eggjs.org/zh-cn/intro/quickstart.html
快速入门
1.安装项目搭建
搭建项目有两种方式:使用脚手架安装和不适用脚手架安装
//使用脚手架快速生成项目
npm init egg --type=simple
//生成项目后安装插件
npm install
生成后完整的的目录结构如下: 这个时候在控制台上输入npm run dev就可以简单的将项目跑起来了:
首先需要初始化目录结构
npm init //生成package.json
npm i egg --save
npm i egg-bin --save-dev
这个egg-bin就相当于我们经常配的package.json里script命令。通过script去执行egg-bin,这个再去执行egg。
所以需要到package.json里的script中添加dev指令
{
"name": "egg-study-02",
"version": "1.0.0",
"description": "study",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" :"egg-bin dev"
},
"author": "dwb",
"license": "ISC",
"dependencies": {
"egg": "^2.30.0"
},
"devDependencies": {
"egg-bin": "^4.16.4"
}
}
2. 编写controller
web开发中采用的是MVC的设计模式,就会使用到Controller层来接收请求,验证数据,调用指定业务,最后返回结果
那么egg就需要写的是Controller和Router
const Controller = require('egg').Controller;
class TestController extends Controller {
async test() {
this.ctx.body = 'Hello World';
}
}
module.exports = TestController;
在router.js中配置路由映射
'use strict';
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/t1', controller.test.test);
};
保存完毕后,npm run dev 启动项目看看是否配置成功
3. 静态文件
- app 文件夹下面会有public文件夹,没有这个文件夹会自动创建。
- 在这个文件夹下建立的文件,在里面写上的内容,然后去访问http://127.0.0.1:7001/public/加文件名就可以访问到文件的内容。
4. 模板渲染
模板渲染比较像java的thymeleaf这样的模板引擎,看起来就是作用于前后端不分离这样的项目,有好处也有坏处
安装插件 egg-view-nunjucks:
npm install egg-view-nunjucks --save
开启插件:
exports.nunjucks = {
enable: true,
package: 'egg-view-nunjucks',
};
module.exports = {
nunjucks: {
enable: true,
package: 'egg-view-nunjucks',
},
};
这里的config是根目录下的config
模板文件的默认放置路径为app/view下
<html>
<head>
<title>Hacker News</title>
<link rel="stylesheet" href="/public/css/news.css" />
</head>
<body>
<ul class="news-view view">
{% for item in list %}
<li class="item">
<a href="{{ item.url }}">{{ item.title }}</a>
</li>
{% endfor %}
</ul>
</body>
</html>
添加新闻的controller和router
news.js
const Controller = require('egg').Controller;
class NewsController extends Controller {
async list() {
const dataList = {
list: [
{ id: 1, title: 'this is news 1', url: '/news/1' },
{ id: 2, title: 'this is news 2', url: '/news/2' },
],
};
await this.ctx.render('news/list.tpl', dataList);
}
}
module.exports = NewsController;
修改router.js
'use strict';
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/t1', controller.test.test);
router.get('news', controller.news.list);
};
访问http://127.0.0.1:7001/news 如下图:
5. 调用远程接口
因为在实际的应用中,controller是不会产出数据的,也不会有复杂的业务逻辑,复杂的过程应该抽象为业务逻辑层service,所以
我们写一个接口,新建newsService.js,去接受返回的数据
const axios = require('axios');
const Service = require('egg').Service;
class NewsService extends Service {
async getList() {
let list = await axios.get('http://127.0.0.1:8080/news/list')
return list.data.data;
}
}
module.exports = NewsService;
const Controller = require('egg').Controller;
class NewsController extends Controller {
async list() {
const { ctx } = this;
const newsList = ctx.service.newsService.getList();
await this.ctx.render('news/list.tpl', { list: newsList });
}
}
module.exports = NewsController;
运行后的效果为:
6. 计划任务
- 计划任务一般指有计划的做的任务,常见的是定时任务
- 计划任务放在app下的schedule文件夹
- 有了计划任务拿数据就不需要每次要时都去请求,而是应该每天去请求一次,然后缓存下,下次就直接从缓存拿就可以了。
- 先写个接口,可以获取到数据,为了方便查看取数据没有,加个时间戳:
@GetMapping("/cache")
public String getSchedule(){
User user = new User();
user.setTitle("每日更换标题 "+new Date());
return JSON.toJSONString(user);
}
- 在app下建立schedule文件夹,写个文件updateTitle.js。文件名不是定死的,文件夹名是定死的。
const { Subscription } = require('egg')
module.exports = class extends Subscription {
static get schedule() {
return {
interval: '5s',
type: 'all'
}
}
async subscribe() {
let res = await this.ctx.curl('http://127.0.0.1:8080/cache', {
method: 'GET',
dataType: 'json'
})
console.log(res.data);
this.ctx.app.cache = res.data
}
}
控制台效果如下:
module.exports = {
schedule: {
cron: '0 0 */3 * * *',
},
};
效果如下:
|