摘要:插件機制可以說是自定義的鉤子函數。首先在新建文件夾,新建文件以為例更新內容緩存里對應的數組表示鉤子函數的調用名,具體調用的是下面的方法。
一.簡介
這個個人博客網站最初制作的目的就是練習使用thinkJs,這一篇就主要講一下thinkJs的一些特性和注意事項。涉及到了文件上傳,thinkJs的插件機制,model層建立以及CURD的編寫方式等。本項目github地址在這里。
項目thinkJs端主要參考了知乎上大佬Ischo的文章,鏈接在這。
二.thinkJs model層寫法
這里主要講兩個部分,一是表對應的js文件,二是CRUD寫法。項目表結構比較簡單,一共八個表,包含多對一,一對多,多對多關系。主要的幾個表,都對應著model文件夾下的js文件,表關系也在這個js里維護。這里我們以model/content.js為例講一哈:
module.exports = class extends think.Model { // 模型關聯 get relation() { return { category: { type: think.Model.BELONG_TO, model: "meta", key: "category_id", fKey: "id", field: "id,name,slug,description,count" }, tag: { type: think.Model.MANY_TO_MANY, model: "meta", rModel: "relationship", rfKey: "meta_id", key: "id", fKey: "content_id", field: "id,name,slug,description,count" }, comment: { type: think.Model.HAS_MANY, key: "id", fKey: "content_id", where: "status=99", order: "create_time desc" }, user: { type: think.Model.BELONG_TO, model: "user", key: "user_id", fKey: "id", field: "id,username,email,qq,github,weibo,zhihu" } }; } // 添加文章 async insert(data) { const tags = data.tag; data = this.parseContent(data); delete data.tag; const id = await this.add(data); const relation = []; tags.forEach(val => { relation.push({ content_id: id, meta_id: val }); }); think.model("relationship").addMany(relation); // 更新文章數量 this.updateCount(data.category_id, tags); return id; } }
這里代碼沒有截全,完整代碼看github。
我們看到這個對象分為兩部分,一個是get relation寫的表映射關系??梢钥吹絚ontent表與meta表存在一對一關系(type: think.Model.BELONG_TO),這里key:category_id是content表里的字段,即外鍵,fkey:id是對應的meta表里的字段。查詢時,會封裝層user.category對象,對象屬性就是field 定義的id,name,slug,description,count。content 與user也存在多對多關系(type: think.Model.MANY_TO_MANY),rfModel是多對多關系下,對應的關聯關系模型名,默認值為二個模型名的組合,rfKey是多對多關系下,關系表對應的 key。
另一個是Model里的方法,相當于自定義的model方法,比如這里定義的insert,就可以在controller里通過this.model("content").insert()調用。
thinkJS的CRUD操作,不是直接寫sql,而是在sql基礎上封裝一層,通過調用model的方法來操作。think.Model?基類提供了豐富的方法進行 CRUD 操作,具體如下:
查詢數據 模型提供了多種方法來查詢數據,如: find 查詢單條數據 select 查詢多條數據 count 查詢總條數 countSelect 分頁查詢數據 max 查詢字段的最大值 avg 查詢字段的平均值 min 查詢字段的最小值 sum 對字段值進行求和 getField 查詢指定字段的值 同時模型支持通過下面的方法指定 SQL 語句中的特定條件,如: where 指定 SQL 語句中的 where 條件 limit / page 指定 SQL 語句中的 limit field / fieldReverse 指定 SQL 語句中的 field order 指定 SQL 語句中的 order group 指定 SQL 語句中的 group join 指定 SQL 語句中的 join union 指定 SQL 語句中的 union having 指定 SQL 語句中的 having cache 設置查詢緩存 添加數據 模型提供了下列的方法來添加數據: add 添加單條數據 thenAdd where 條件不存在時添加 addMany 添加多條數據 selectAdd 添加子查詢的結果數據 更新數據 模型提供了下列的方法來更新數據: update 更新單條數據 updateMany 更新多條數據 thenUpdate 條件式更新 increment 字段增加值 decrement 字段減少值 刪除數據 模型提供了下列的方法來刪除數據: delete 刪除數據 手動執行 SQL 語句 有時候模型包裝的方法不能滿足所有的情況,這時候需要手工指定 SQL 語句,可以通過下面的方法進行: query 手寫 SQL 語句查詢 execute 手寫 SQL 語句執行
比如我們要查詢content表數據,在Controller里通過thin.model("content").where(param).select()來查詢。
thinkJs的Model層與之前用過的java的數據層框架hibernate比較相似,都是基于面向對象的思想對sql進行封裝,表與Model(實體類),通過model方法進行CRUD操作,特別省sql。
三.插件機制的實現
參考的博主實現的插件機制還是很好用的,這里我就拿了過來。插件機制可以說是自定義的鉤子函數。首先在src新建service文件夾,新建js文件(以cache.js為例)
module.exports = class extends think.Service { static registerHook() { return { content: ["contentCreate", "contentUpdate", "contentDelete"] }; } /** * 更新內容緩存 * @param {[type]} data [description] * @return {[type]} [description] */ content(data) { think.cache("recent_content", null); } };
registerHook里content對應的數組表示鉤子函數的調用名,具體調用的是下面的content方法。在controller里這么調用
await this.hook("contentUpdate", data);
鉤子函數的注冊這里放到了worker進程里,thinkJs運行流程具體的可以看看官網在這里
work.js代碼如下:
think.beforeStartServer(async () => { const hooks = []; for (const Service of Object.values(think.app.services)) { const isHookService = think.isFunction(Service.registerHook); if (!isHookService) { continue; } const service = new Service(); const serviceHooks = Service.registerHook(); for (const hookFuncName in serviceHooks) { if (!think.isFunction(service[hookFuncName])) { continue; } let funcForHooks = serviceHooks[hookFuncName]; if (think.isString(funcForHooks)) { funcForHooks = [funcForHooks]; } if (!think.isArray(funcForHooks)) { continue; } for (const hookName of funcForHooks) { if (!hooks[hookName]) { hooks[hookName] = []; } hooks[hookName].push({ service, method: hookFuncName }); } } } think.config("hooks", hooks); });
這里將service里定義的method遍歷取出,按一定格式保存并存放到數組,最后放到think.config里面,項目啟動后這些過程就已經執行了。
think.Controller本身沒有hook方法,這里需要在extend里面加上controller.js,代碼如下:
module.exports = { /** * 執行hook * @param {[type]} name [description] * @param {...[type]} args [description] * @return {[type]} [description] */ async hook(name, ...args) { const { hooks } = think.config(); const hookFuncs = hooks[name]; if (!think.isArray(hookFuncs)) { return; } for (const { service, method } of hookFuncs) { await service[method](...args); } } };
這樣自定義鉤子函數就實現了,一些通用的后置方法就可以直接共用一個了。
四.路由
thinkJs路由寫在config/router.js里,具體代碼如下:
module.exports = [ // RESTFUL [//api/(w+)(?:/(.*))?/, "api/:1?id=:2", "rest"], [//font/(w+)/(w+)/, "fontend/:1/:2"], ["/:category/:slug", "content/detail"], ["/:category/:slug/comment", "content/comment"] ];
里面的數組的第一個元素是匹配url的表達式,第二個元素是分配的資源,如果是采用RESTFUL規范定義的接口,第三個元素要寫作"rest"。本項目的后臺接口基本都是采用RESTFUL規范,具體路由的詳細講解可以看官網鏈接
五.部署
項目線上部署采用PM2管理node進程,部署時把src,view,www,pm2.json,production.js放到服務器上。安裝好pm2后運行
pm2 start pm2.json
注意pm2.json里需要修改cwd為服務器上你項目的目錄。本項目前后端是一個服務,不存在所以沒有用nginx代理。thinkJs部署相關可以看這里
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/53743.html
摘要:插件機制可以說是自定義的鉤子函數。首先在新建文件夾,新建文件以為例更新內容緩存里對應的數組表示鉤子函數的調用名,具體調用的是下面的方法。 一.簡介 這個個人博客網站最初制作的目的就是練習使用thinkJs,這一篇就主要講一下thinkJs的一些特性和注意事項。涉及到了文件上傳,thinkJs的插件機制,model層建立以及CURD的編寫方式等。本項目github地址在這里。 項目thi...
摘要:插件機制可以說是自定義的鉤子函數。首先在新建文件夾,新建文件以為例更新內容緩存里對應的數組表示鉤子函數的調用名,具體調用的是下面的方法。 一.簡介 這個個人博客網站最初制作的目的就是練習使用thinkJs,這一篇就主要講一下thinkJs的一些特性和注意事項。涉及到了文件上傳,thinkJs的插件機制,model層建立以及CURD的編寫方式等。本項目github地址在這里。 項目thi...
摘要:首先看下的代碼編譯前刪除之前編譯生成的靜態資源首先需要改的是入口文件,因為是多頁面應用,需要多個入口文件來保證打包成不同的。 一.項目簡介 ? ? 本項目使用vue作為前端框架,thinkJs作為后端框架,構建個人博客網站,頁面分為博客展示和后臺管理,主要目的是學習使用thinkJs?,F在只完成了主要的博客增刪改功能,發現webpack的配置遇到了一些坑,這里先記錄下。項目目錄結構如下...
摘要:首先看下的代碼編譯前刪除之前編譯生成的靜態資源首先需要改的是入口文件,因為是多頁面應用,需要多個入口文件來保證打包成不同的。 一.項目簡介 ? ? 本項目使用vue作為前端框架,thinkJs作為后端框架,構建個人博客網站,頁面分為博客展示和后臺管理,主要目的是學習使用thinkJs。現在只完成了主要的博客增刪改功能,發現webpack的配置遇到了一些坑,這里先記錄下。項目目錄結構如下...
摘要:一入冬懶癌發作,給自己找點事干。之前博客程序寫過幾次,的寫過兩次,用寫過,隨著版本從升級到之前的博客程序也做過升級。這里主要記錄一下開發過程中遇到的問題和解決方法。后端使用守護進程即可。 一入冬懶癌發作,給自己找點事干。之前博客程序寫過幾次,php 的寫過兩次,nodejs 用 ThinkJS 寫過,隨著 ThinkJS 版本從1.x 升級到 2.x 之前的博客程序也做過升級。但是因為...
閱讀 1320·2021-09-27 13:56
閱讀 2353·2019-08-26 10:35
閱讀 3513·2019-08-23 15:53
閱讀 1862·2019-08-23 14:42
閱讀 1244·2019-08-23 14:33
閱讀 3575·2019-08-23 12:36
閱讀 1961·2019-08-22 18:46
閱讀 1010·2019-08-22 14:06