欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

egg.js的基本使用實(shí)例

 更新時(shí)間:2022年04月18日 09:47:39   作者:@逆風(fēng)boy  
本文主要介紹了egg.js的基本使用實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

安裝egg.js

全局切換鏡像: 
npm config set registry https://registry.npm.taobao.org

我們推薦直接使用腳手架,只需幾條簡(jiǎn)單指令,即可快速生成項(xiàng)目(npm >=6.1.0):

mkdir egg-example && cd egg-example
npm init egg --type=simple --registry https://registry.npm.taobao.org
npm i

啟動(dòng)項(xiàng)目:

npm run dev
open http://localhost:7001

寫(xiě)第一個(gè)api接口

安裝vscode擴(kuò)展

創(chuàng)建控制器

async index() {
    const { ctx } = this;
    // 獲取路由get傳值參數(shù)(路由:id)
    ctx.params;
    // 獲取url的問(wèn)號(hào)get傳值參數(shù)
    ctx.query;
    // 響應(yīng)
    ctx.body = '響應(yīng)';
    // 狀態(tài)碼
	ctx.status = 201;
}

編寫(xiě)路由

基礎(chǔ)用法

// router.js
router.get('/admin/:id', controller.admin.index);

// controller
async index() {
    const { ctx } = this;
    // 獲取路由get傳值參數(shù)(路由:id)
    ctx.params;
    // 獲取url的問(wèn)號(hào)get傳值參數(shù)
    ctx.query;
}

資源路由

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.resources('posts', '/api/posts', controller.posts);
  // app/controller/v1/users.js
  router.resources('users', '/api/v1/users', controller.v1.users); 
};

上面代碼就在 /posts 路徑上部署了一組 CRUD 路徑結(jié)構(gòu),對(duì)應(yīng)的 Controller 為 app/controller/posts.js 接下來(lái), 你只需要在 posts.js 里面實(shí)現(xiàn)對(duì)應(yīng)的函數(shù)就可以了。

MethodPathRoute NameController.Action
GET/postspostsapp.controllers.posts.index
GET/posts/newnew_postapp.controllers.posts.new
GET/posts/:idpostapp.controllers.posts.show
GET/posts/:id/editedit_postapp.controllers.posts.edit
POST/postspostsapp.controllers.posts.create
PUT/posts/:idpostapp.controllers.posts.update
DELETE/posts/:idpostapp.controllers.posts.destroy
// app/controller/posts.js

// 列表頁(yè)
exports.index = async () => {};
// 新增表單頁(yè)
exports.new = async () => {};
// 新增邏輯
exports.create = async () => {};
// 詳情頁(yè)
exports.show = async () => {};
// 編輯表單頁(yè)
exports.edit = async () => {};
// 更新邏輯
exports.update = async () => {};
// 刪除邏輯
exports.destroy = async () => {};

路由分組

// 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);
};

關(guān)閉csrf開(kāi)啟跨域

文檔:https://www.npmjs.com/package/egg-cors

安裝npm i egg-cors --save

配置插件

// {app_root}/config/plugin.js
exports.cors = {
  enable: true,
  package: 'egg-cors',
};

config / config.default.js 目錄下配置

  config.security = {
    // 關(guān)閉 csrf
    csrf: {
      enable: false,
    },
     // 跨域白名單
    domainWhiteList: [ 'http://localhost:3000' ],
  };
  // 允許跨域的方法
  config.cors = {
    origin: '*',
    allowMethods: 'GET, PUT, POST, DELETE, PATCH'
  };

數(shù)據(jù)庫(kù)

配置和創(chuàng)建遷移文件

配置 安裝并配置egg-sequelize插件(它會(huì)輔助我們將定義好的 Model 對(duì)象加載到 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:  'eggapi',
    // 中國(guó)時(shí)區(qū)
    timezone:  '+08:00',
    define: {
        // 取消數(shù)據(jù)表名復(fù)數(shù)
        freezeTableName: true,
        // 自動(dòng)寫(xiě)入時(shí)間戳 created_at updated_at
        timestamps: true,
        // 字段生成軟刪除時(shí)間戳 deleted_at
        paranoid: true,
        createdAt: 'created_at',
        updatedAt: 'updated_at',
        deletedAt: 'deleted_at',
        // 所有駝峰命名格式化
        underscored: true
    }
};

sequelize 提供了sequelize-cli工具來(lái)實(shí)現(xiàn)Migrations,我們也可以在 egg 項(xiàng)目中引入 sequelize-cli。

npm install --save-dev sequelize-cli

egg 項(xiàng)目中,我們希望將所有數(shù)據(jù)庫(kù) Migrations 相關(guān)的內(nèi)容都放在database目錄下,所以我們?cè)陧?xiàng)目根目錄下新建一個(gè).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

行完后會(huì)生成database/config.json文件和database/migrations目錄,我們修改一下database/config.json中的內(nèi)容,將其改成我們項(xiàng)目中使用的數(shù)據(jù)庫(kù)配置:

{
  "development": {
    "username": "root",
    "password": null,
    "database": "eggapi",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "timezone": "+08:00"
  }
}

創(chuàng)建數(shù)據(jù)庫(kù)

npx sequelize db:create

創(chuàng)建數(shù)據(jù)遷移表

npx sequelize migration:generate --name=init-user

1.執(zhí)行完命令后,會(huì)在database / migrations / 目錄下生成數(shù)據(jù)表遷移文件,然后定義

'use strict';

module.exports = {
    up: async (queryInterface, Sequelize) => {
        const { INTEGER, STRING, DATE, ENUM } = Sequelize;
        // 創(chuàng)建表
        await queryInterface.createTable('user', {
            id: { type: INTEGER(20).UNSIGNED, primaryKey: true, autoIncrement: true },
            username: { type: STRING(30), allowNull: false, defaultValue: '', comment: '用戶名稱', unique: true},
            password: { type: STRING(200), allowNull: false, defaultValue: '' },
            avatar_url: { type: STRING(200), allowNull: true, defaultValue: '' },
            sex: { type: ENUM, values: ['男','女','保密'], allowNull: true, defaultValue: '男', comment: '用戶性別'},
            created_at: DATE,
            updated_at: DATE
        });
    },

    down: async queryInterface => {
        await queryInterface.dropTable('user')
    }
};

執(zhí)行 migrate 進(jìn)行數(shù)據(jù)庫(kù)變更

# 升級(jí)數(shù)據(jù)庫(kù)
npx sequelize db:migrate
# 如果有問(wèn)題需要回滾,可以通過(guò) `db:migrate:undo` 回退一個(gè)變更
# npx sequelize db:migrate:undo
# 可以通過(guò) `db:migrate:undo:all` 回退到初始狀態(tài)
# npx sequelize db:migrate:undo:all

模型

創(chuàng)建模型

// app / model / user.js

'use strict';
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  // 配置(重要:一定要配置詳細(xì),一定要?。。。?
  const User = app.model.define('user', {
    id: { type: INTEGER(20).UNSIGNED, primaryKey: true, autoIncrement: true },
      username: { type: STRING(30), allowNull: false, defaultValue: '', comment: '用戶名稱', unique: true},
      password: { type: STRING(200), allowNull: false, defaultValue: '' },
      avatar_url: { type: STRING(200), allowNull: true, defaultValue: '' },
      sex: { type: ENUM, values: ['男','女','保密'], allowNull: true, defaultValue: '男', comment: '用戶性別'},
      created_at: DATE,
      updated_at: DATE
  },{
    timestamps: true, // 是否自動(dòng)寫(xiě)入時(shí)間戳
    tableName: 'user', // 自定義數(shù)據(jù)表名稱
 });

  return User;
};

這個(gè) Model 就可以在 Controller 和 Service 中通過(guò) app.model.User 或者 ctx.model.User 訪問(wèn)到了,例如我們編寫(xiě) app/controller/user.js

// app/controller/user.js
const Controller = require('egg').Controller;

function toInt(str) {
  if (typeof str === 'number') return str;
  if (!str) return str;
  return parseInt(str, 10) || 0;
}

class UserController extends Controller {
  async index() {
    const ctx = this.ctx;
    let keyword = this.ctx.params.keyword;
    let Op = this.app.Sequelize.Op;
    ctx.body = await ctx.model.User.findAll({ 
        where:{
            id:{
                [Op.gt]:6
            },
            username: {
              	[Op.like]:'%'+keyword+'%'
            }
        },
        attributes:['id','username','sex'],
        order:[
            ['id','DESC']
        ],
        limit: toInt(ctx.query.limit), 
        offset: toInt(ctx.query.offset) 
    });
  }

  async show() {
    let id = parseInt(this.ctx.params.id);
      // 通過(guò)主鍵查詢單個(gè)數(shù)據(jù)
      // let detail = await this.app.model.User.findByPk(id);
      // if (!detail) {
      //     return this.ctx.body = {
      //         msg: "fail",
      //         data: "用戶不存在"
      //     }
      // }

      // 查詢單個(gè)
      let detail = await this.app.model.User.findOne({
          where: {
              id,
              sex: "女"
          }
      });

      this.ctx.body = {
          msg: 'ok',
          data: detail
      };
  }

  async create() {
    const ctx = this.ctx;
    const { name, age } = ctx.request.body;
    // 創(chuàng)建單條記錄
    const user = await ctx.model.User.create({ name, age });
    // 批量創(chuàng)建
    await ctx.model.User.bulkCreate([{
        name: "第一個(gè)",
        age: 15
    },
    {
        name: "第二個(gè)",
        age: 15
    },
    {
        name: "第三個(gè)",
        age: 15
    }]);
    ctx.status = 201;
    ctx.body = user;
  }

  async update() {
    const ctx = this.ctx;
    const id = toInt(ctx.params.id);
    const user = await ctx.model.User.findByPk(id);
    if (!user) {
      ctx.status = 404;
      return;
    }

    const { name, age } = ctx.request.body;
    await user.update({ name, age });
    ctx.body = user;
  }

  async destroy() {
    const ctx = this.ctx;
    const id = toInt(ctx.params.id);
    const user = await ctx.model.User.findByPk(id);
    if (!user) {
      ctx.status = 404;
      return;
    }

    await user.destroy();
    ctx.status = 200;
  }
}

module.exports = UserController;

最后我們將這個(gè) controller 掛載到路由上:

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.resources('user', '/user', controller.user);
};

針對(duì) users 表的 CURD 操作的接口就開(kāi)發(fā)完了

錯(cuò)誤和異常處理

// app/middleware/error_handler.js
module.exports = (option, app) => {
    return async function errorHandler(ctx, next) {
      try {
        await next();
      } catch (err) {
        // 所有的異常都在 app 上觸發(fā)一個(gè) error 事件,框架會(huì)記錄一條錯(cuò)誤日志
        ctx.app.emit('error', err, ctx);
  
        const status = err.status || 500;
        // 生產(chǎn)環(huán)境時(shí) 500 錯(cuò)誤的詳細(xì)錯(cuò)誤內(nèi)容不返回給客戶端,因?yàn)榭赡馨舾行畔?
        const error = status === 500 && ctx.app.config.env === 'prod'
          ? 'Internal Server Error'
          : err.message;
  
        // 從 error 對(duì)象上讀出各個(gè)屬性,設(shè)置到響應(yīng)中
        ctx.body = { error };
        if (status === 422) {
          ctx.body.detail = err.errors;
        }
        ctx.status = status;
      }
    };
  };

中間件

config.middleware = ['errorHandler'];

config.errorHandler = {
    ceshi: 123,
    // 通用配置(以下是重點(diǎn))
    enable:true, // 控制中間件是否開(kāi)啟。
    match:'/news', // 設(shè)置只有符合某些規(guī)則的請(qǐng)求才會(huì)經(jīng)過(guò)這個(gè)中間件(匹配路由)
    ignore:'/shop' // 設(shè)置符合某些規(guī)則的請(qǐng)求不經(jīng)過(guò)這個(gè)中間件。

    /**
        注意:
        1. match 和 ignore 不允許同時(shí)配置
        2. 例如:match:'/news',只要包含/news的任何頁(yè)面都生效
        **/

    // match 和 ignore 支持多種類型的配置方式:字符串、正則、函數(shù)(推薦)
    match(ctx) {
        // 只有 ios 設(shè)備才開(kāi)啟
        const reg = /iphone|ipad|ipod/i;
        return reg.test(ctx.get('user-agent'));
    },
};

參數(shù)驗(yàn)證

https://www.npmjs.com/package/egg-valparams

npm i egg-valparams --save
// config/plugin.js
valparams : {
  enable : true,
  package: 'egg-valparams'
},
// config/config.default.js
config.valparams = {
    locale    : 'zh-cn',
    throwError: false
};
class XXXController extends app.Controller {
  // ...
  async XXX() {
    const {ctx} = this;
    ctx.validate({
      system  : {type: 'string', required: false, defValue: 'account', desc: '系統(tǒng)名稱'},
      token   : {type: 'string', required: true, desc: 'token 驗(yàn)證'},
      redirect: {type: 'string', required: false, desc: '登錄跳轉(zhuǎn)'}
    });
    // if (config.throwError === false)
    if(ctx.paramErrors) {
      // get error infos from `ctx.paramErrors`;
    }
    let params = ctx.params;
    let {query, body} = ctx.request;
    // ctx.params        = validater.ret.params;
    // ctx.request.query = validater.ret.query;
    // ctx.request.body  = validater.ret.body;
    // ...
    ctx.body = query;
  }
  // ...
}

 到此這篇關(guān)于egg.js的基本使用實(shí)例的文章就介紹到這了,更多相關(guān)egg.js基本使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 用javascript作一個(gè)通用向?qū)дf(shuō)明

    用javascript作一個(gè)通用向?qū)дf(shuō)明

    向?qū)Э梢宰屇愕木W(wǎng)站用戶快速上手使用你的web應(yīng)用,提高網(wǎng)站的吸引力。向?qū)б话惴譃楹脦讉€(gè)步驟,每個(gè)步驟收集一些數(shù)據(jù),并且支持退回功能,所有步驟完成后可以得到每一步的收集結(jié)果。這里給大家展示一種比較通用,靈活且簡(jiǎn)單的向?qū)Э蚣堋?/div> 2011-08-08
  • 微信小程序?qū)崿F(xiàn)兩邊小中間大的輪播效果的示例代碼

    微信小程序?qū)崿F(xiàn)兩邊小中間大的輪播效果的示例代碼

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)兩邊小中間大的輪播效果的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • MVVM框架下實(shí)現(xiàn)分頁(yè)功能示例

    MVVM框架下實(shí)現(xiàn)分頁(yè)功能示例

    分頁(yè)這種組件,幾乎每一種框架都有這樣的組件,這篇文章主要介紹了MVVM框架下實(shí)現(xiàn)分頁(yè)功能示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 詳解JavaScript的回調(diào)函數(shù)

    詳解JavaScript的回調(diào)函數(shù)

    這篇文章主要介紹了JavaScript的回調(diào)函數(shù),幫助大家正確理解和使用 JavaScript中的回調(diào)函數(shù),感興趣的小伙伴們可以參考一下
    2015-11-11
  • 動(dòng)態(tài)生成的IFRAME,設(shè)置SRC時(shí)的問(wèn)題解決分析

    動(dòng)態(tài)生成的IFRAME,設(shè)置SRC時(shí)的問(wèn)題解決分析

    動(dòng)態(tài)生成的IFRAME,設(shè)置SRC時(shí)的,不同位置帶來(lái)的影響。 以下所說(shuō)的是在IE7下運(yùn)行的。IE6下也是同樣。 在這個(gè)blog中,直接點(diǎn)擊運(yùn)行代碼,和把下面代碼保存到為網(wǎng)頁(yè)在運(yùn)行(以本地文件或域名訪問(wèn)),效果不一樣。 先看例子:
    2008-04-04
  • 如何檢查一個(gè)對(duì)象是否為空

    如何檢查一個(gè)對(duì)象是否為空

    這篇文章主要介紹了js如何檢查一個(gè)對(duì)象是否為空,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 淺談typescript中keyof與typeof操作符用法

    淺談typescript中keyof與typeof操作符用法

    本文主要介紹了typescript中keyof與typeof操作符用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 全面了解addEventListener和on的區(qū)別

    全面了解addEventListener和on的區(qū)別

    下面小編就為大家?guī)?lái)一篇全面了解addEventListener和on的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-07-07
  • 簡(jiǎn)單漂亮的js彈窗可自由拖拽且兼容大部分瀏覽器

    簡(jiǎn)單漂亮的js彈窗可自由拖拽且兼容大部分瀏覽器

    js彈窗想必大家都有見(jiàn)到過(guò)吧,如何要說(shuō)可以自由拖拽,并兼容大部分瀏覽器的就沒(méi)有幾個(gè)了吧,本文的這個(gè)示例或許是大家要找的,可以參考下
    2013-10-10
  • 如何利用JS檢查元素是否在視口內(nèi)

    如何利用JS檢查元素是否在視口內(nèi)

    這篇文章主要給大家介紹了關(guān)于如何利用JS檢查元素是否在視口內(nèi)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論