zoukankan      html  css  js  c++  java
  • 推荐一个NodeJS 框架 AdonisJS

    它是一个 服务端渲染 的 MVC 框架。如果熟悉 Laravel 框架(PHP 框架),你会发现这是 Laravel 的一个 NodeJS 版本。如果你熟悉Laravel PHP框架的话,上手AdonisJS 就很容易了。它是Laravel的缩小版。

    AdonisJS 文档 暂时没得中文文档

    项目的结构

    Http Server

    Http Request

    • AdonisJS 中,为了方便接收 HTTP 请求信息,所有的控制器方法和路由器闭包都会接收一个 Request 实例 。请看一下简单示例:
    // 路由闭包中调用 request ,response
    const Route = use('Route')
    
    Route.get('post', function * (request, response) {
      const body = request.all()
       
      // cherry picking fields
      const body = request.only('title', 'description', 'categories')
    })
    
    // 控制器中调用 request, response
    class IndexController {
      * index(requset, response) {
        // ...
      }
    }
    
    • request.all() :包括所有查询字符串和请求体:
    const data = request.all()
    // example.html?id=1&name=John 
    // <input name="gender" value="male" />
    // => {"id":1, "name": "John", "gender": "male" }
    
    • request.only():跟 request.all() 类似,但是只包含定义的 key 值:
    const data = request.only('name', 'email', 'age')
    /* returns
    {
      'name': '..',
      'email':'..',
      'age':'..'
    }
    */
    
    • request.input(key,[defaultValue]):返回 input 标签对应的键值对,如果 value 为空,则返回 defaultValue:
    const name = request.input('name')
    const subscribe = request.input('subscribe', 'yes')
    
    • request.url() :获取请求的 URL(出去查询字符串):
    // url - http://foo.com/users?orderBy=desc&limit=10
    request.url()
    // returns - http://foo.com/users
    
    • request.param(key, [defaultValue]) :返回查询字符串:
    // url - http://foo.com/users?orderBy=desc&limit=10
    request.param('orderBy')
    // returns - desc
    
    // 返回所有的查询字符串
    request.params()
    
    • request.collect(key1, key2, ...):转化数据格式,直接看下面例子:
    <form method="POST" action="/users">
      <div class="row">
        <h2> User 1 </h2>
        <input type="email" name="email[]" />
        <input type="password" name="password[]" />
      </div>
    
      <div class="row">
        <h2> User 2 </h2>
        <input type="email" name="email[]" />
        <input type="password" name="password[]" />
      </div>
    
      <button type="submit"> Create Users </button>
    </form>
    
    request.only('email', 'password', )
    /* returns 
    {
      email: ['bar@foo.com', 'baz@foo.com'],
      password: ['secret', 'secret1']
    }
    */
    
    request.collect('email', 'password')
    /* returns
    [
      {
        email: 'bar@foo.com',
        password: 'secret'
      },
      {
        email: 'baz@foo.com',
        password: 'secret1'
      }
    ]
    */
    

    Http Response

    为了方便尽快响应 HTTP 请求,AdonisJS 提供了 response 类给我们使用。可用于渲染 nunjucks views 或者格式化数据。以下是简单的示例代码:

    // Render Views
    Route
      .get('/', function *() {
        yield response.sendView('welcome')    // resources/views/welcome.njk
    })
    
    // JSON Response
    Route
      .get('user', function * () {
        const user = yield User.all()    // fetch users
        response.json(users)
    })
    
    • 常用的还有重定向(Redirects)
    response.location('/signup')
    // or
    response.location('back')
    

    Http Middleware

    中间件的使用十分常见,比如验证用户是否登录。在 AdonisJS 中,中间件放在 app/Http/Middleware 文件夹下,以下是简单示例:

    'use strict'
    
    const geoip = use('geoip-lite')  // npm module
    
    class CountryDetector {
      
      * handle (request, response, next) {
        const ip = request.ip()
        request.country = geoip.lookup(ip).country
        yield next    // 如果想要把 req, res 传递给下个中间件或者路由行为,注意使用 yield next 
      }
    }
    

    MVC 设计模式

    整个架构的数据流程如果下图所示:

    Model

    Model 是从数据库(AdonisJS 使用的是 SQL)获取数据的数据层,为了使获取数据的过程简单和安全,Adonis 使用了很好的 ORM 架构(Lucid

    Controller

    控制器主要控制 HTTP 请求数据流,利用 Model 获取必要的数据(不仅数据库,第三方服务器的数据等都在控制器里边处理),并把获取的数据传递给 View 去渲染 HTML 页面。

    // 引入依赖文件
    const path = require('path')
    
    // 定义控制器
    class UsersController {
    
      // 依赖注入
      static get inject () {
        return ['App/Model/User']   
      }
    
      // 以参数形式接收依赖注入
      constructor (User) { 
        this.User = User 
      }
      
      // 自定义数据处理方法
      static _processUserInfo() {
        // ...
      }
      
      // 异步调用的方法
      * index () {
        const users = yield this.User.all()
        // 传递数据给视图渲染
        yield response.sendView('users',{
            userName,
            userInfo
        })
      }
    
    }
    
    module.exports = UserController
    

    View

    View 是整个 MVC 模式数据流的最后部分,主要是利用动态的数据(Nunjuck Template)去渲染(jinja 引擎) HTML 页面。
    正如前边的数据流图所述,View 便是整个数据流程的末端,即利用前边步骤传来的数据进行页面渲染。AdonisJS 的视图引擎是建立在 nunjucks 的基础上的,所以 nunjucks 有的模板语法,在 AdonisJS 中一样可以使用。另外,AdonisJS 也提供了一些特有的 过滤器(filter)。

    // Route
    const Route = use('Route')
    Route.get('/greet/:user', 'UserController.greet')
    
    // Controller
    class UserController {
      * greet (request, response) {
         const user = request.param('user')  // user: "John"
         yield response.sendView('greet', {user})
      }
    }
    
    // View
    <h2>Hello {{ user }}</h2>    // <h2>John</h2>
    
    

    Http Rounting

    • 路由部分的代码书写在 app/Http/routes.js 中,简单的例子如下
    const Route = use('Route')    // 类似 include,跟 require 不同
    
    Route.get('/', function * (request, response) {
        yield response.sendView('home')    // 这里使用 ES6 generator 语法达到异步请求数据的效果
    })
    
    • 路由参数:路由参数是 URL 中的动态数据段,我们可以通过自定义的 URL 接受动态数据。如下例子:
    Route.get('users/:id', function * (request, response) {
        const id = request.param('id')
        response.send('Profile for user with id ${id}')
    })
    
    • 路由群:通常,会存在一系列路由共享同一个模块的情况,这就可能有时候需要修改这个模块的一些共同参数,我们把这些路由“集合”到一起,就方便修改了。例如下面的例子:
    Route.group('version1', function () {
        Route.get('users', function * (request, response) {  // 路由是 /api/v1/users
            // ...
        })
    }).prefix('api/v1').middleware('auth')    // 该路由群都会加上 api/v1 的前缀,并经过用户登录中间件的检验
    
    • 路由命名:书写完整的路径有时过于麻烦,为方便使用可以给路由命名。如下例子:
    Route
        .get('users/:id', '与否.show')
        .as('profile') 
    

    IoC Container 依赖注入 & Service Providers 服务依赖注入

    Ioc Container 主要概念就是在容器内存储/绑定依赖关系,然后从容器中取回它们,而不是手动请求它们

    • IoC Container 绑定依赖关系示例代码如下:
    const Ioc = require('adonis-fold').Ioc
    const bugsnag = require('bugsnag')
    
    Ioc.bind('Adonis/Src/Bugsnag', function (app) { 
    
      const Config = app.use('Adonis/Src/Config') 
      const bugSnagConfig = Config.get('services.bugsnag') 
    
      bugsnag.register(bugSnagConfig.apiKey, bugSnagConfig.options) 
      return bugsnag 
    
    })
    
    • 绑定 Service Provider 的示例代码如下:
    const ServiceProvider = require('adonis-fold').ServiceProvider
    
    class BugSnagProvider extends ServiceProvider {
    
      * register () { 
        this.app.bind('Adonis/Addons/BugSnag', (app) => {
          const BugSnag = require('./BugSnag')
          const Config = app.use('Adonis/Src/Config')
          return new BugSnag(Config)
        })
      }
    
      * boot () { 
        // Everything is registered do some hard work
      }
    
    }
    
  • 相关阅读:
    在终端聊天
    Vue双向数据绑定的原理
    手动封装on,emit,off
    浅谈Vue中组件传值的几种方式
    常见的一些性能优化的小方法
    常见的一些JS兼容问题
    移动布局的方法
    移动布局的方法
    快速、高效的学习vuex
    移动端300ms延迟原因及解决方案
  • 原文地址:https://www.cnblogs.com/boyGdm/p/15593222.html
Copyright © 2011-2022 走看看