天天看點

Egg.js快速入門

Egg.js

基于Node.js和Koa企業級應用開發架構

特性

提供基于Egg的定制上層架構的能力

高度可擴充的插件機制

内置多程序管理

基于Koa開發性能優異

架構穩定,測試覆寫率搞

漸進式開發

涉及内容

vant ui

vue

-cli3

moment.js

mysql

前後端聯調

開發環境

https://eggjs.org/zh-cn/intro/quickstart.html
$ node -v
v10.16.0

$ mkdir egg-demo && cd egg-demo
$ npm init egg --type=simple
$ cnpm i
$ npm run dev      
http://127.0.0.1:7001/

路由

app/router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
};      

GET傳參

1、方式一

/product/detail?id=110

// 路由
router.get('/product/detail', controller.product.detail);

// 控制器
async detail() {
    const { ctx } = this;
    console.log(ctx.query); // { id: '110' }
    ctx.body = `id=${ctx.query.id}`;
}      

2、方式二

/product/detail2/110

// 路由
router.get('/product/detail2/:id', controller.product.detail2);

// 控制器
async detail2() {
    const { ctx } = this;
    console.log(ctx.params); // { id: '110' }
    ctx.body = `id=${ctx.params.id}`;
}
      

POST請求

// 配置檔案關閉csrf
config.security = {
    csrf: {
      enable: false,
    },
  };

// 路由
router.post('/product/create', controller.product.create);


// 控制器
async create() {
    const { ctx } = this;
    console.log(ctx.request.body); // { name: 'Tom' }

    const {name, age} = ctx.request.body;
    ctx.body = {name, age};
  }
      

POST請求 /product/create

Content-Type application/x-www-form-urlencoded
Content-Type application/json

name: "Tom"      

傳回

{
    "name": "Tom"
}      

PUT請求

/product/update/110

// 路由
router.put('/product/update/:id', controller.product.update);

// 控制器
async update() {
    const { ctx } = this;
    console.log(ctx.params); // { id: '110' }
    ctx.body = {id: ctx.params.id};
  }      

DELETE請求

/product/delete/110

// 路由
router.delete('/product/delete/:id', controller.product.delete);

// 控制器
async delete() {
    const { ctx } = this;
    console.log(ctx.params); // { id: '110' }
    ctx.body = {
        id: ctx.params.id
    };
  }      

Service

app/service/product.js

'use strict';

const Service = require('egg').Service;

class productService extends Service {
  async index() {
      return {
          name: "Tom",
          age: 18
      };
  }
}

module.exports = productService;
      
// 路由
router.get('/product', controller.product.index);

// 修改控制器使用service
async index() {
    const { ctx } = this;
    const res = await ctx.service.product.index();
    ctx.body = res;
  }      

通路後傳回: /product/

{
    "name": "Tom",
    "age": 18
}      

模闆引擎

ejs

https://github.com/eggjs/egg-view-ejs
$ npm i egg-view-ejs      

文法參考

https://ejs.bootcss.com/

修改配置

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

// {app_root}/config/config.default.js
config.view = {
  mapping: {
    '.html': 'ejs',
  },
};      

建立檔案

app/view/index.html

<%# 變量 #%>
<%=res.name%>
<%=res.age%>


<%# for循環 #%>
<% for(var i=0; i<list.length; i++){ %>
  <p><%=list[i]%></p>    
<% } %>      

控制器中渲染

async index() {
    const { ctx } = this;
    const res = await ctx.service.product.index();
    // ctx.body = res;
    await ctx.render('index.html', {
      res,
      list: ['red', 'green', 'blue']
    })
  }      

靜态資源

app/public目錄樹

app
  ├── public
      ├── css
      │   └── main.css
      ├── img
      │   └── demo.png
      └── js
          └── main.js      
<!-- 引入css檔案 -->
<link rel="stylesheet" href="/public/css/main.css">

<!-- 引入圖檔資源 -->
<img src="/public/img/demo.png" alt="">

<!-- 引入js檔案 -->
<script src="/public/js/main.js"></script>      

mysql插件

npm i --save egg-mysql      
// config/plugin.js
exports.mysql = {
  enable: true,
  package: 'egg-mysql',
};

// config/config.default.js
config.mysql = {
    // 單資料庫資訊配置
    client: {
      // host
      host: '127.0.0.1',
      // 端口号
      port: '3306',
      // 使用者名
      user: 'root',
      // 密碼
      password: '123456',
      // 資料庫名
      database: 'data',
    },
    // 是否加載到 app 上,預設開啟
    app: true,
    // 是否加載到 agent 上,預設關閉
    agent: false,
  };      

查詢

async index() {
    const { ctx, app } = this;
    const res = await app.mysql.select("article");
    console.log(res);
  }      

前端開發

1、腳手架 @vue/cli

https://cli.vuejs.org/zh/guide/installation.html
$ cnpm install -g @vue/cli

$ vue -V
3.12.0

$ vue --help

$ vue create client

$ cd client

$ npm run serve      

http://localhost:8080/

2、前端元件庫 vant

https://youzan.github.io/vant/#/zh-CN/quickstart
$ npm i vant -S
$ npm i babel-plugin-import -D      

在 .babelrc 中添加配置

{
  "plugins": [
    ["import", {
      "libraryName": "vant",
      "libraryDirectory": "es",
      "style": true
    }]
  ]
}      

App.vue引入vant元件

<template>
  <div id="app">
    <van-button type="primary">按鈕元件</van-button>
  </div>
</template>

<script>
import { Button } from 'vant';

export default {
  name: 'app',

  components: {
    [Button.name]: Button
  }
}
</script>
      

3、路由vue-router

cnpm i vue-router --save      

4、處理時間

cnpm i moment --save      
// 後端儲存之前
const moment = require('moment');

const create_time = moment().format('YYYY-MM-DD HH:mm:ss');
// 2019-10-13 22:29:23

//前端展示之前
import momemt from 'moment';

this.list = res.data.map(item=>{
  if(item.create_time){
    item.create_time  = moment(item.create_time).format('YYYY-MM-DD HH:mm:ss');
  }
  return item;
});      

5、用戶端跨域請求

vue.config.js

module.exports = {
    // 處理跨域請求
    devServer: {
        proxy: {
            '/article': {
                target: "http://127.0.0.1:7001/",
                ws: true, // 允許websockt服務
                changeOrigin: true // 開啟虛拟伺服器,請求代理伺服器
            }
        }
    }
}      

繼續閱讀