egg.js 实例总结

544 阅读3分钟

关于环境的搭建及初始化,请读者移步官方文挡 egg.js

app 第一个重要的文件夹

egg开发的主战场,常说的MVC模式: view、controller、model都在此文件中,先了解一下本文件的目录结构

目录结构

├── 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 (可选)

router.js

主要根据url来调用controller显示不同过的页面

'use strict' // 开启严格模式
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  router.get('/', controller.home.index);
  // 当访问/lists时,就会找到controller中lists.js文件的方法index(),将方法中渲染的任容呈现到页面中
  router.get('/lists', controller.lists.index)
};

MVC 框架 - controller 文件

主要负责业务逻辑的处理(简单业务逻辑)

  • 在controller文件中新建lists.js文件
  • 用于控制lists路径的展示
// controller/lists.js
'use strict' // 开启严格模式
// 获取 Controller 基类
const Controller = require('egg').Controller
// 实例对象,规定ListsController命名必须与本文件名lists.js成对应关系,大写Lists+Controller
class ListsController extends Controller {
    // 函数前使用异步 async
    async index() {
        // ctx为当前请求的Context实例
        const {ctx} = this
        // 访问路由 /lists 页面呈现 lists.js
        ctx.body = 'lists.js'
        let result = 'lists.js'
        // .render() 用于渲染html页面,异步使用await
        // 第一个参数被渲染的html文件
        // 第二个参数使用传递给页面用于展示的数据
        await ctx.render('lists.html', {result})
    }
}
// 必须导出
module.exports = ListsController

MVC 框架 - view 文件

主要用于视图模板页面展示

  • 在view中新建lists.html文件
  • 模板页面中需要用到依赖 egg-view-ejs,使用npm下载
<body>
    <div>
        <h2>新闻详情页</h2>
        <!-- 
            <%=data%>
            使用此种方法获取controller的数据
        -->
        // 接收result数据并展示
        <h3><%=result%></h3>
    </div>
</body>

MVC 框架 - service 文件

主要和数据库打交道(查询数据库,请求数据,复杂的业务逻辑,数据操作等)

// 新建文件lists.js
'use strict'
// 获取Service基类
const Service = require('egg').Service
// 实例化对象,命名规则和controller类似
class ListsService extends Service {
    async getLists() {
        // 通过抓取接口返回数据
        // 通过curl方法获取远程数据
        let url = this.config.api + 'appapi.php?a=getPortalList&catid=20&page=1'
        // this.ctx.curl获取接口数据
        let response = await this.ctx.curl(url)
        response = JSON.parse(response.data)
        // 将数据返回给调用者
        return response.result
    }
}
module.exports = ListsService

修改controllerl中的lists.js中的方法,调用servce中lists.js中的方法获取数据

// controller/lists.js
    async index() {
        const {ctx} = this
        // 获取service中的lists.js的getLists()数据
        let result = await this.service.lists.getLists()
        // 将需要展示的数据传送给模板
        await ctx.render('lists.html', {result})
    }

修改view中lists.html文件

<body>
    <div>
        <h2>新闻列表数据</h2>
        <ul>
            <!--
                for循环语法:
                <%for(let i=0;i<result.length;i++){%>
                    // 被循环的元素
                <%}%>
            -->
            <%for(let i=0;i<result.length;i++){%>
            <li>
                <a href="/listcontent?aid=<%=result[i].aid%>"><%=result[i].title%></a>
                // helper.formateTime() 扩展的工具函数
                <span> 发布时间: <%=helper.formatTime(result[i].dateline)%></span>
            </li>
            <%}%>
        </ul>
    </div>
</body>

以上的流程是:

  • 当用户访问url为 /lists 的地址时
  • 通过路由router.js匹配,找到controller.lists.index
    // router.js
    router.get('/lists', controller.lists.index)
    
  • 调用controller文件中lists.js的index()函数,通过ctx.render()渲染指定页面lists.html
  • lists.html根据this.ctx.render('lists.html', {result})参数渲染页面需要的数据

未完待续