egg.js学习笔记
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了egg.js学习笔记相关的知识,希望对你有一定的参考价值。
文章目录
- 安装egg
- 目录结构
- 路由相关
- 重定向
- 控制器
- 模板引擎
- 服务(模型)
- 模型和数据库
- 扩展
- 中间件
- 表单提交
- cookie
- session
- 定时任务
- API
- 常用插件
安装egg
我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0
):
mkdir egg-example && cd egg-example
npm init egg --type=simple
npm i
启动项目:
npm run dev
open http://localhost:7001
目录结构
egg-project
├── package.json
├── app.js (可选)
├── agent.js (可选)
├── app(-----------核心------------)
| ├── router.js(路由)
│ ├── controller(控制器)
│ | └── home.js
│ ├── service (模型)
│ | └── user.js
│ ├── middleware (中间件)
│ | └── response_time.js
│ ├── schedule (可选)
│ | └── my_task.js
│ ├── public (静态资源)
│ | └── reset.css
│ ├── view (模板视图)
│ | └── home.tpl
│ └── extend (扩展)
│ ├── helper.js (可选)
│ ├── request.js (可选)
│ ├── response.js (可选)
│ ├── context.js (可选)
│ ├── application.js (可选)
│ └── agent.js (可选)
├── config
| ├── plugin.js
| ├── config.default.js
│ ├── config.prod.js
| ├── config.test.js (可选)
| ├── config.local.js (可选)
| └── config.unittest.js (可选)
└── test
├── middleware
| └── response_time.test.js
└── controller
└── home.test.js
路由相关
1. get传值
// router.js
router.get('/admin/:id', controller.admin.index);
// controller
async index(ctx)
// 获取路由get传值参数(路由:id)
ctx.params;
// 获取url的问号get传值参数
ctx.query;
2. 4种配置方法
router.verb('path-match', app.controller.action);
router.verb('router-name', 'path-match', app.controller.action);// 第一个参数可以给name
router.verb('path-match', middleware1, ..., middlewareN, app.controller.action);
router.verb('router-name', 'path-match', middleware1, ..., middlewareN, app.controller.action);
重定向
1. ctx
async index()
this.ctx.status = 301; // 把重定向改为301
this.ctx.redirect('/admin/add'); // 默认临时重定向 302
2. 路由重定向
app.router.redirect('/', '/home/index', 302);
3.路由分组
// app/router.js
module.exports = app =>
require('./router/news')(app);
require('./router/admin')(app);
;
// app/router/news.js
module.exports = app =>
app.router.get('/news/list', app.controller.news.list);
app.router.get('/news/detail', app.controller.news.detail);
;
// app/router/admin.js
module.exports = app =>
app.router.get('/admin/user', app.controller.admin.user);
app.router.get('/admin/log', app.controller.admin.log);
;
控制器
自定义 Controller 基类
// app/core/base_controller.js
const Controller = require('egg');
class BaseController extends Controller
get user()
return this.ctx.session.user;
success(data)
this.ctx.body =
success: true,
data,
;
notFound(msg)
msg = msg || 'not found';
this.ctx.throw(404, msg);
module.exports = BaseController;
此时在编写应用的 Controller 时,可以继承 BaseController,直接使用基类上的方法:
//app/controller/post.js
const Controller = require('../core/base_controller');
class PostController extends Controller
async list()
const posts = await this.service.listByUser(this.user);
this.success(posts);
模板引擎
1. 安装和使用ejs
(1)安装:
npm i egg-view-ejs --save
(2)配置:/config
config/config.default.js
module.exports = appInfo =>
...
config.view =
mapping:
'.html': 'ejs',
,
;
...
;
config/plugin.js
module.exports =
// 配置ejs
ejs:
enable: true,
package: 'egg-view-ejs',
;
(3)使用
app/controller
async index()
const ctx = this;
// 渲染变量
let msg = "测试内容";
let list = [1, 2, 3, 4, 5, 6];
// 渲染模板(render需要加await)
await ctx.render('index',
msg,
list
);
app/view/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--渲染变量-->
<%=msg%>
<ul>
<% for(var i=0; i < list.length; i++) %>
<li>
<%=list[i]%>
</li>
<% %>
</ul>
<!--加载 app/public 下的资源文件-->
<img src="/public/images/find.png">
</body>
</html>
服务(模型)
控制器调用 home
模型的 ceshi
方法
await this.service.home.ceshi();
模型之间相互调用(同上)
模型和数据库
配置和创建迁移文件
配置
- 安装并配置egg-sequelize插件(它会辅助我们将定义好的 Model 对象加载到 app 和 ctx 上)和mysql2模块:
npm install --save egg-sequelize mysql2
- 在
config/plugin.js
中引入 egg-sequelize 插件
exports.sequelize =
enable: true,
package: 'egg-sequelize',
;
- 在
config/config.default.js
config.sequelize =
dialect: 'mysql',
host: '127.0.0.1',
username: 'root',
password: 'root',
port: 3306,
database: 'friends',
// 中国时区
timezone: '+08:00',
define:
// 取消数据表名复数
freezeTableName: true,
// 自动写入时间戳 created_at updated_at
timestamps: true,
// 字段生成软删除时间戳 deleted_at
paranoid: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
// 所有驼峰命名格式化
underscored: true
;
- sequelize 提供了sequelize-cli工具来实现Migrations,我们也可以在 egg 项目中引入 sequelize-cli。
npm install --save-dev sequelize-cli
- egg 项目中,我们希望将所有数据库 Migrations 相关的内容都放在
database
目录下,所以我们在项目根目录下新建一个.sequelizerc
配置文件:
'use strict';
const path = require('path');
module.exports =
config: path.join(__dirname, 'database/config.json'),
'migrations-path': path.join(__dirname, 'database/migrations'),
'seeders-path': path.join(__dirname, 'database/seeders'),
'models-path': path.join(__dirname, 'app/model'),
;
- 初始化 Migrations 配置文件和目录
npx sequelize init:config
npx sequelize init:migrations
// npx sequelize init:models
- 行完后会生成
database/config.json
文件和database/migrations
目录,我们修改一下database/config.json
中的内容,将其改成我们项目中使用的数据库配置:
"development":
"username": "root",
"password": null,
"database": "test",
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00"
- 创建数据库
npx sequelize db:create
创建数据迁移表
npx sequelize migration:generate --name=init-users
1.执行完命令后,会在database / migrations / 目录下生成数据表迁移文件,然后定义
'use strict';
module.exports =
up: async (queryInterface, Sequelize) =>
const INTEGER, STRING, DATE, ENUM = Sequelize;
// 创建表
await queryInterface.createTable('users',
id: type: INTEGER(20).UNSIGNED, primaryKey: true, autoIncrement: true ,
username: type: STRING(30), allowNull: false, defaultValue: '', comment: '用户名称', unique: true,
email: type: STRING(160), allowNull: false, defaultValue: '', comment: '用户邮箱', unique: true ,
password: type: STRING(200), allowNull: false, defaultValue: '' ,
avatar_url: type: STRING(200), allowNull: true, defaultValue: '' ,
mobile: type: STRING(20), allowNull: false, defaultValue: '', comment: '用户手机', unique: true ,
prifix: type: STRING(32), allowNull: false, defaultValue: '' ,
abstract: type: STRING(255), allowNull: true, defaultValue: '' ,
role_id:
type: INTEGER,
// 定义外键(重要)
references:
model: 'users', // 对应表名称(数据表名称)
key: 'id' // 对应表的主键
,
onUpdate: 'restrict', // 更新时操作
onDelete: 'cascade' // 删除时操作
,
gender: type: ENUM, values: ['男','女','保密'], allowNull: true, defaultValue: '男', comment: '用户性别',
created_at: DATE,
updated_at: DATE
, engine: 'MYISAM' );
// 添加索引
queryInterface.addIndex('users', ['gender']);
// 添加唯一索引
queryInterface.addIndex('users',
name: "name", // 索引名称
unique: true, // 唯一索引
fields: ['name'] // 索引对应字段
);
,
down: async queryInterface =>
await queryInterface.dropTable('users')
;
- 执行 migrate 进行数据库变更
# 升级数据库
npx sequelize db:migrate
# 如果有问题需要回滚,可以通过 `db:migrate:undo` 回退一个变更
# npx sequelize db:migrate:undo
# 可以通过 `db:migrate:undo:all` 回退到初始状态
# npx sequelize db:migrate:undo:all
已创建新增字段
1.创建迁移文件:
npx sequelize migration:generate --name=user-addcolumn
2.执行完命令后,会在database / migrations / 目录下生成数据表迁移文件,然后定义
'use strict';
module.exports =
up: (queryInterface, Sequelize) =>
return queryInterface.sequelize.transaction((t) =>
return Promise.all([
queryInterface.addColumn('user', 'role_id',
type: Sequelize.INTEGER
, transaction: t ),
queryInterface.addColumn('user', 'ceshi',
type: Sequelize.STRING,
, transaction: t )
])
)
,
down: (queryInterface, Sequelize) =>
return queryInterface.sequelize.transaction((t) =>
return Promise.all([
queryInterface.removeColumn('user', 'role_id', transaction: t ),
queryInterface.removeColumn('user', 'ceshi', transaction: t )
])
)
;
3.执行 migrate 进行数据库变更
npx sequelize db:migrate
创建模型
// app / model / user.js
'use strict';
module.exports = app =>
const STRING, INTEGER, DATE = app.Sequelize;
// 配置(重要:一定要配置详细,一定要!!!)
const User = app.model.define('user',
id: type: INTEGER, primaryKey: true, autoIncrement: true ,
name: STRING(30),
age: INTEGER,
created_at: DATE,
updated_at: DATE,
,
timestamps: true, // 是否自动写入时间戳
tableName: 'users', // 自定义数据表名称
);
return User;
;
这个 Model 就可以在 Controller 和 Service 中通过 app.model.User
或者 ctx.model.User
访问到了,例如我们编写 app/controller/users.js
:
// app/controller/users.js
const Controller = require('egg').Controller;
function toInt(str)
if (typeof str === 'number') return str;
if (!str) return str;
return parseInt(str, 10) || 以上是关于egg.js学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
egg.js + react 实战:从 0 到 1 实现记账本小册学习笔记合集(持续更新中)
egg.js + react + zarm ui + vite2.0 全栈项目实战:从 0 到 1 实现记账本小册学习笔记合集(完结)