ThinkJs入门

TinkJs入门

本文是以thinkjs3.0版本为参照讲解的,如有不理解的部分,请参照:https://thinkjs.org/zh-cn/doc/3.0/create_project.html

1.项目创建

全局安装thinkjs

$ npm install -g think-cli

创建并执行项目

$ thinkjs new demo;
$ cd demo;
$ npm install; 
$ npm start;

项目结构:

|--- development.js   //开发环境下的入口文件
|--- nginx.conf  //nginx 配置文件
|--- package.json
|--- pm2.json //pm2 配置文件
|--- production.js //生产环境下的入口文件
|--- README.md
|--- src
| |--- bootstrap  //启动自动执行目录 
| | |--- master.js //Master 进程下自动执行
| | |--- worker.js //Worker 进程下自动执行
| |--- config  //配置文件目录
| | |--- adapter.js  // adapter 配置文件 
| | |--- config.js  // 默认配置文件 
| | |--- config.production.js  //生产环境下的默认配置文件,和 config.js 合并 
| | |--- extend.js  //extend 配置文件 
| | |--- middleware.js //middleware 配置文件 
| | |--- router.js //自定义路由配置文件
| |--- controller  //控制器目录 
| | |--- base.js
| | |--- index.js
| |--- service  //服务目录 
| | |--- **.js //用户自己定义的服务
| |--- logic //logic 目录
| | |--- index.js
| |--- model //模型目录
| | |--- index.js
|--- view  //模板目录
| |--- index_index.html
|--- www
| |--- static  //静态资源目录
| | |--- css
| | |--- img
| | |--- js

默认情况下,项目启动端口为8360,执行成功后浏览器可通过http://127.0.0.1:8360/访问项目。

2.路由(router)

thinkjs的默认路由配置如下:

module.exports = [
  {
    handle: 'router',
    options: {
      defaultModule: 'home',
      defaultController: 'index',
      defaultAction: 'index',
      prefix: [],
      suffix: ['.html'],
      enableDefaultRouter: true,
      subdomainOffset: 2,
      subdomain: {},
      denyModules: []
    }
  }
];

我们可以手动在src/config/router.js下修改默认的配置。

路由解析:

默认情况下路由解析规则为:/controller/action

多模块项目的解析规则为:/module/controller/action

如果controller下有子级,那么解析规则为:/controller/子级/action。

查找action时根据路由action名查找,如果未指定则查找indexAction。

例如:

http://127.0.0.1:8360/ :该路径请求controllerindex.js中的indexAction方法。

http://127.0.0.1:8360/demo/demo:该路径请求controllerdemo子级的demo.js中的indexAction方法。

3.控制器(controller)

控制器主要是对用户的请求进行分发和处理。

module.exports = class extends think.Controller {
    __before() {
        //action执行之前调用,如果返回false则不再执行action
    }
    async indexAction() {
        let data = await this.model('demo').select();
        return this.success(data);
        // return this.display();
    }

    demoAction() {
        const req = this.ctx.req;   //获取request
        const res = this.ctx.res;   //获取response
        return this.display("index_index.html");
    }

    __after() {
        //action 执行完成后执行,如果 action 返回了 false 则不再执行
    }

    __call() {
        //找不到对应的action时执行,可做统一处理
    }
};

4.数据校验层(Logic)

通常情况下,服务端拿到数据后会先对数据进行正确性校验,才会进行之后的逻辑处理。所以thinkjs在controller之前加入了logic层,目的就是对数据进行校验。

Logic中的Action必须和Controller中的Action一一对应。

module.exports = class extends think.Logic {
  indexAction(){
    this.rules = {
      username: {
        string: true,       // 字段类型为 String 类型
        required: true,     // 字段必填
        default: 'thinkjs', // 字段默认值为 'thinkjs'
        trim: true,         // 字段需要trim处理
        method: 'GET'       // 指定获取数据的方式
      },
      age: {
        int: {min: 20, max: 60} // 20到60之间的整数
      }
    }
  }
}

logic会优先执行,校验成功后则进入controller进行逻辑处理。

5.模型层(Modle)

thinkjs在src/config/extend.js已经通过model(think.app)引入了所有的关联模型,所以不需要我们做特殊处理。在该模块中可以定义一些实体或者存储一些复杂的数据查询方法。

6.视图层(View)

配置 src/config/extend.js来支持View

const view = require('think-view');
module.exports = [
  view
]

配置 src/config/adapter.js设置视图默认配置

const nunjucks = require('think-view-nunjucks');
const path = require('path');

// 视图的 adapter 名称为 view
exports.view = {
  type: 'nunjucks', // 这里指定默认的模板引擎是 nunjucks
  common: {
    viewPath: path.join(think.ROOT_PATH, 'view'), //模板文件的根目录
    sep: '_', //Controller 与 Action 之间的连接符
    extname: '.html' //模板文件扩展名
  },
  nunjucks: {
    handle: nunjucks,
    beforeRender: () => {}, // 模板渲染预处理
    options: { // 模板引擎额外的配置参数

    }
  }
}

三个与视图相关的重要方法:

assign:给模版赋值。

//单条赋值
this.assign('title', 'thinkjs'); 

//多条赋值
this.assign({
  title: 'thinkjs', 
  name: 'test'
}); 

//获取之前赋过的值,如果不存在则为 undefined
const title = this.assign('title'); 

//获取所有赋的值
const assignData = this.assign();

render:获取渲染后的内容。

该方法是异步方法,需要通过asyns/await来处理。

//根据当前请求解析的 controller 和 action 自动匹配模板文件
const content1 = await this.render(); 

//指定文件名
const content2 = await this.render('doc'); 
const content3 = await this.render('doc/detail'); 
const content4 = await this.render('doc_detail');

//不指定文件名但切换模板类型
const content5 = await this.render(undefined, 'ejs');

//指定文件名且切换模板类型
const content6 = await this.render('doc', 'ejs'); 

//切换模板类型,并配置额外的参数
//切换模板类型时,需要在 adapter 配置里配置对应的类型
const content7 = await this.render('doc', {
  type: 'ejs', 
  xxx: 'yyy'
});

display:渲染并输出内容,该方法实际上是调用了 render 方法,然后将渲染后的内容赋值到 ctx.body 属性上。该方法为异步方法,需要通过 async/await 处理。

//根据当前请求解析的 controller 和 action 自动匹配模板文件
await this.display(); 

//指定文件名
await this.display('doc'); 
await this.display('doc/detail'); 
await this.display('doc_detail');

//不指定文件名切换模板类型
await this.display(undefined, 'ejs');

//指定文件名且切换模板类型
await this.display('doc', 'ejs'); 

//切换模板类型,并配置额外的参数
await this.display('doc', {
  type: 'ejs', 
  xxx: 'yyy'
});

7.中间件配置(middleware)

中间件是为了更方便的处理用户请求,Thinkjs3是基于Koa2构建的。所以中间件的处理格式为:

module.exports = options => {
  return (ctx, next) => {
    // do something
  }
}

在Koa2中要使用中间件需通过app.use(‘中间件’)的方式。

为了更加统一的维护和管理中间件,所以Thinjs3提供了src/config/middleware.js文件进行中间件配置。

const path = require('path');
const isDev = think.env === 'development';

module.exports = [
  {
    handle: 'meta',
    options: {
      logRequest: isDev,
      sendResponseTime: isDev
    }
  },
  {
    handle: 'resource',                             //中间件的处理函数
    enable: isDev,                                  //是否启用中间件
    options: {                                      //中间件配置参数,可以是一个函数
      root: path.join(think.ROOT_PATH, 'www'),      
      publicPath: /^\/(static|favicon\.ico)/
    },
     match:'/www/static'                            //匹配特定的规则后才能执行中间件,可以是路径或匹配函数
  }
]

8.数据库配置

模型支持多种多个数据库的,其配置路径为src/config/adapter.js

const mysql = require('think-model-mysql');
exports.model = {
  type: 'mysql', // 默认使用的类型,调用时可以指定参数切换
  common: { // 通用配置
    logConnect: true, // 是否打印数据库连接信息
    logSql: true, // 是否打印 SQL 语句
    logger: msg => think.logger.info(msg) // 打印信息的 logger
  },
  mysql: { // mysql 配置
    handle: mysql
  },
  mysql2: { // 另一个 mysql 的配置
    handle: mysql
  },
  sqlite: {  // sqlite 配置

  },
  postgresql: { // postgresql 配置

  }
}

当项目用到多个数据库的时候,可以通过type来区分。

const user1 = think.model(‘user’); // 使用默认的数据库配置

const user2 = think.model(‘user’, ‘mysql2’); // 使用 mysql2 的配置

9.系统服务启动流程

这里写图片描述

10.用户请求流程

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值