框架中内置 think
全局对象,方便在项目中随时随地使用。
think.app
为 Koa Application 对象的实例,系统启动时生成。
此外为 app 扩展了更多的属性。
think.app.think
等同于 think 对象,方便有些地方传入了 app 对象,同时要使用 think 对象上的其他方法think.app.modules
模块列表,单模块项目下为空数组think.app.controllers
存放项目下的 controller 文件,便于后续快速调用think.app.logics
存放项目下的 logic 文件think.app.models
存放项目下的模型文件think.app.services
存放 service 文件think.app.routers
存放自定义路由配置think.app.validators
存放校验配置think.app.server
创建 HTTP 服务后的 server 对象如果想要查下这些属性具体的值,可以在 appReady
事件中进行。
think.app.on('appReady', () => {
console.log(think.app.controllers)
})
项目的根目录,其他目录可以通过该目录来生成,如:
const runtimePath = path.join(think.ROOT_PATH, 'runtime/');
const viewPath = path.join(think.ROOT_PATH, 'view/');
APP 根目录,默认为 ${think.ROOT_PATH}/app
,如果项目不需要转译的话,那么默认路径为:${think.ROOT_PATH}/src
。
当前运行环境,等同于 think.app.env
,值在 development.js
之类的入口文件中定义。
当前 ThinkJS 的版本号。
name
{String} 配置名value
{Mixed} 配置值m
{String} 模块名,多模块项目下使用读取或者设置配置,该功能由 think-config 模块实现。在 context、controller、logic 上可以直接通过 this.config
方法来操作配置。
// 获取配置
const value1 = think.config('name');
// 指定模块获取配置,多模块项目下有效
const value2 = think.config('name', undefined, 'admin');
// 设置配置
think.config('name', 'value');
// 指定模块设置配置值
think.config('name', 'value', 'admin');
控制器基类,其他控制器类继承该类。
// src/controller/user.js
module.exports = class userController extends think.Controller {
indexAction() {
}
}
Logic 基类,继承自 think.Controller
。
// src/logic/user.js
module.exports = class userLogic extends think.Logic {
indexAction() {
}
}
Service 基类,其他 Service 类继承该类。
// src/service/sms.js
module.exports = class extends think.Service {
}
name
{String} Service 名称m
{String} 模块名,多模块项目下有效...args
{Array} 实例化 Service 类需要的参数。单模块项目下,会把 m
参数补充导 args 里。实例化 Service 类,如果导出的对象不是个类,那么直接返回。
const instance1 = think.service('sms');
const instance2 = think.service('sms', 'admin');
fn
{Function} 要注册的函数名服务启动之前要注册执行的函数,如果有异步操作,fn 需要返回 Promise。
array
{any} 判断输入是否是数组return
{Boolean}判断是否是数组,等同于 Array.isArray
。
think.isArray([]); // true
think.isArray({}); // false
boolean
{any}判断输入是否是布尔值
think.isBoolean(false); // true
any
{any}判断输入的是否是整数
any
{any}判断输入是 null
,也可以直接通过 xxx === null
来判断。
any
{any}判断输入是 null
或者 undefined
number
{any}判断输入是否是数字
think.isNumber(1); // true
str
{any}判断输入是否是字符串
any
{any}判断输入是否是 Symbol 类型
any
{any}判断输入是否是 undefined,也可以直接通过 xxx === undefined
来判断。
reg
{any}判断输入是否是正则对象
date
{any}判断输入是否是日期对象
error
{any}判断输入是否是Error类型
any
{any}判断输入是否是函数类型
any
{any}判断输入是否是原始类型,包含:null
、string
、boolean
、number
、symbol
、undefined
。
ip
{String}判断一个字符串是否是 ip 地址,IP v4 或者 IP v6,等同于 net.isIP
。
buffer
{any}判断输入是否是一个Buffer对象,等同于 Buffer.isBuffer
。
ip
{String}判断一个字符串是否是 IP v4 地址,等同于 net.isIPv4
。
ip
{String}判断一个字符串是否是 IP v6 地址,等同于 net.isIPv6
判断当前进程是否为主进程,等同于 cluster.isMaster
obj
{any}判断一个输入是否为 Object,通过 Object.prototype.toString.call(obj)
是否为 [object Object]
判断
think.isObject({}); // true
think.isObject([]); // false
think.isObject(null); // false
fn
{Function} 要包装的函数receiver
{Object} 要绑定作用域的对象此方法把一个 callback 函数包装 成Promise
let fn = think.promisify(fs.readFile, fs);
let data = await fn(__filename);
target
{Object} 要extend的目标对象...any
{Object} 可以有任意多个对象深拷贝对象,如果 key 相同,那么后面的值会覆盖前面的值。
think.extend({a: 1}, {b: 2});
// return {a:1,b:2};
think.extend({a: 1}, {a: 2});
// return {a: 2}
str
{String}把字符串转成驼峰表示法
think.camelCase('index_index');
// return 'indexIndex'
str
{String}把驼峰写法转化为蛇形写法
think.snakeCase('indexIndex');
// return 'index_index'
str
{String}判断输入是不是一个字符串类型的数字
think.isNumberString('419');
// return true
any
{any}判断是否是真正的空,undefined
、null
、''
、NaN
为 true,其他为 false。
think.isTrueEmpty(null);
// return true
any
{any}判断对象是否为空, undefined
, null
,''
, NaN
, []
, {}
, 0
, false
为 true,其他为 false。
think.isEmpty(null);
// return true
生成一个 Deferred 对象。
function test() {
const defer = think.defer();
setTimeout(function() {
defer.reslove('1');
},1000)
return defer.promise
}
test().then((result)=>{
result === '1'
})
obj
{Object} 要操作的对象props
{String | Array} 要忽略的属性,如果是字符串,多个值用逗号隔开忽略对象中的某些属性,返回新的对象
const value = think.omit({a: 1, b: 2, c: 3}, 'a,b');
// value is {c: 3}
str
{String}计算字符串的 md5 值。
num
{Number} 时间,单位为毫秒将 setTimeout 包装为 Promise
think.timeout(1000).then(()=>{
...
})
str
{String}对字符串进行 HTML 转义,转义 <
、>
、"
、'
字符。
data
{Date}format
{String} default 'YYYY-MM-DD HH:mm:ss'返回一个格式化日期
think.datetime(1501406894849)
// return "2017-07-30 17:28:14"
version
{String} v1|v4return
{String}生成 uuid 字符串,符合 RFC4122 规范,基于 uuid 模块。
str
{String}return
{Number}把一个语义化的时间转成毫秒,如果转换失败则抛异常,使用 ms 库转换。
think.ms('2 days') // 1d,10h,1y
// return 172800000
path
{String}检测路径是否存在
think.isExist('/usr/local/bin/node')
// return true
filepath
{String}检测是否是一个文件路径
think.isFile('/usr/local/bin/node')
// return true
filepath
{String}检测是否是一个文件夹路径
think.isDirectory('/usr/local/bin')
// return true
path
{String}mode
{String} default '0777'改变文件或文件夹的权限
think.chmod('/usr/local/bin', '0775')
path
{String} 要创建的目录mode
{String} 文件夹权限,默认为 0777
return
{Boolean}创建文件夹。创建成功返回 true, 失败返回 false。
think.mkdir('/usr/local/bin/thinkjs', '0775')
dir
{String} 文件夹路径prefix
{String} 路径前缀return
{Array} 包含所有文件的数组获取文件夹下的所有文件。
think.getdirFiles('/usr/local/bin')
// return []
path
{String}reserve
{Boolean} 是否保留当前的文件夹,只删除文件夹下的文件删除文件夹和文件夹下的文件,异步操作。
think.rmdir('/usr/local/bin/thinkjs', true).then(()=>{
console.log('删除完成')
})
不建议在插件里(middleware、adapter、extend)里直接使用 think 对象,那样会让插件代码不方便单元测试。如果非要使用的话可以传入 app
对象,然后通过 app.think.xxx
来使用 think 对象上的属性或者方法。
// src/config/middleware.js
module.exports = [
{
handle: xxx
}
];
// xxx middleware
module.exports = (options, app) => {
return (ctx, next) => {
// 通过 app.think.modules 获取项目的模块列表
const modules = app.think.modules;
// 如果是多模块项目下(单模块项目长度始终为 0)
if(modules.length) {
}
}
}