字數:2543javascript
閱讀時間:15分鐘html
上一篇文章咱們講述了JSDuck的詳細用法。那麼,本文筆者就以實例爲基礎,和你們一塊兒,從零開始,搭建一個簡單的API文檔——咱們的第一個API文檔V0.0.1。java
上一篇文章的入口處 ===> JSDuck用法詳解json
首先,咱們肯定框架的基本內容:一個動物基類,而後派生出貓和狗兩個子類。動物基類中有一個動物描述屬性和吃飯方法,其派生類貓擁有奔跑、玩耍兩個方法,外加一個發出聲音的事件。微信
總體內容就這麼多,很是簡單哈,那下面咱們就來看看該如何構建整個框架。markdown
磨刀不誤砍柴工,首先,咱們須要構建好基礎代碼。根據所需內容肯定,咱們須要構建一套完整的建立類和繼承類的方案。那麼,第一步,咱們建立一個base.js文件來盛放基礎代碼。app
var GM = {}; window.GM = GM; /** * 基礎類的通用API類 * @class GM.Util * @author lsjcoder * @docauthor lsjcoder * @static */ GM.Util = { /** * 擴展對象 * @method extend * @static * @param dest * {Object} 任意對象 * @return {Object} 擴展後的對象 */ extend : function(dest) { // (Object[, Object, ...]) -> var sources = Array.prototype.slice.call(arguments, 1), i, j, len, src; for (j = 0, len = sources.length; j < len; j++) { src = sources[j] || {}; for (i in src) { if (src.hasOwnProperty(i)) { dest[i] = src[i]; } } } return dest; } };
在建立好的文件內,咱們先編寫上述代碼。咱們先聲明瞭類 GM.Util ,在類的註釋上添加 @static
標籤表示靜態類。靜態類中包含一個方法 extend ,實現了一個簡單的擴展功能,後面類的繼承須要用到這個接口。(這裏須要注意,靜態類中,全部的成員也都是靜態的。所以,全部的成員必須加上@static
標籤)。框架
/** * 全部類的基類 * @class GM.Class */ GM.Class = function() { /** * @property {String} version 版本號 * @readonly */ this.version = "0.0.1"; };
聲明頂層基類 GM.Class ,框架中全部的類都派生自該類。類中聲明瞭一個 version 屬性,該屬性是字符串類型,而且是隻讀屬性。函數
/** * 基類的擴展方法 * @method extend * @static * @param {Object} * props 包含須要擴展的成員的對象 * @return {Object} 擴展後的類 */ GM.Class.extend = function(props) { // extended class with the new prototype var NewClass = function() { // call the constructor if (this.initialize) { this.initialize.apply(this, arguments); } // call all constructor hooks if (this._initHooks) { this.callInitHooks(); } }; // instantiate class without calling constructor var F = function() { }; F.prototype = this.prototype; var proto = new F(); proto.constructor = NewClass; NewClass.prototype = proto; // inherit parent's statics for ( var i in this) { if (this.hasOwnProperty(i) && i !== 'prototype') { NewClass[i] = this[i]; } } // mix static properties into the class if (props.statics) { GM.Util.extend(NewClass, props.statics); delete props.statics; } // mix includes into the prototype if (props.includes) { GM.Util.extend.apply(null, [ proto ].concat(props.includes)); delete props.includes; } // merge options if (props.options && proto.options) { props.options = GM.Util.extend({}, proto.options, props.options); } // mix given properties into the prototype GM.Util.extend(proto, props); proto._initHooks = []; var parent = this; // jshint camelcase: false NewClass.__super__ = parent.prototype; // add method for calling all hooks proto.callInitHooks = function() { if (this._initHooksCalled) { return; } if (parent.prototype.callInitHooks) { parent.prototype.callInitHooks.call(this); } this._initHooksCalled = true; for (var i = 0, len = proto._initHooks.length; i < len; i++) { proto._initHooks[i].call(this); } }; return NewClass; };
基類GM.Class中包含一個靜態方法,用於實現類的繼承機制。後續代碼中類的封裝和繼承都是使用該方法完成的。工具
/** * @enum GM.Enum.Sex 性別枚舉 */ GM.Enum.Sex = { /** * 男 */ "0":"男", /** * 女 */ "1":"女" }
基礎代碼中,還聲明瞭一個性別枚舉,以供後續使用。
至此,基礎代碼構建完畢。
在這個環節中,咱們須要構建一個動物基類。首先,咱們建立一個animal.js文件盛放代碼。
文件完整代碼以下:
/** * 動物類 * @class GM.Animal * @alias Animal * @abstract * @extends GM.Class * @new * @author lsjcoder * @docauthor lsjcoder */ GM.Animal = GM.Class.extend({ /** * @method constructor * @cfg {Object} configs 傳入參數 * @cfg {String} configs.name 姓名 * @cfg {Number} configs.age 年齡 * @cfg {"男"/"女"} configs.sex 性別 */ initialize:function(configs){ this.props.name = configs.name; this.props.age = configs.age; this.props.sex = configs.sex; }, /** * @property {Object} props 屬性 * @property {String} props.name 姓名 * @property {Number} props.age 年齡 * @property {GM.Enum.Sex} props.sex 性別 * @property {String} props.color 顏色 * @property {String} props.type 品種 */ props:{ name:"", age:0, sex:"男", color:"", type:"" }, /** * 吃飯 * @method eat * @abstract * @param {String} food 食物 * @return {Boolean} 是否進食 */ eat:function(food){ if(food != null || food !== ""){ return true; } return false; } });
咱們建立了一個動物類 GM.Animal ,該類不須要實現任何方法,因此,咱們給他添加一個抽象標籤 @abstract
代表該類是一個抽象類。@extends GM.Class
代表了該類派生自 GM.Class 類,@new
標籤表示此類是這個版本新增長的內容。
類中有一個 initialize 方法,它是類的構造函數。因此咱們用註釋 @method constructor
標記它爲構造函數,而後使用 @cfg
標籤描述構造函數所需參數。這裏,構造函數所需參數是一個對象,對象中有多個屬性,因此咱們使用如上配置方式來分別描述每個屬性。類中還有一個 props 屬性,描述了動物的基本信息,該屬性也是一個對象,註釋方式同上述 @cfg
。最後,類中還有抽象方法 eat ,該方法接收一個字符串類型參數並返回一個布爾類型的結果。
接下來,咱們須要構建動物類的兩個派生類:貓類和狗類。咱們分別建立兩個代碼文件:cat.js、dog.js。
cat.js文件中代碼以下:
/** *貓 * *``` *示例: *var pCat = new GM.Cat({ * name:"Kity", * age:1, * sex:"女" *}) *``` * * @class GM.Cat * @extends GM.Animal * @alias Cat * @author lsjcoder * @docauthor lsjcoder * @uses GM.Dog * */ GM.Cat = GM.Animal.extend({ /** * @method constructor * @cfg {Object} configs 傳入參數 * @cfg {String} configs.name 姓名 * @cfg {Number} configs.age 年齡 * @cfg {"男"/"女"} configs.sex 性別 */ initialize:function(configs){ this.props.name = configs.name; this.props.age = configs.age; this.props.sex = configs.sex; /** * @event say 發出叫聲 * @param {GM.Cat} this 當前實例 * @param {String} value 叫聲 */ this.fireEvent("say", this, value); }, /** * @method run 奔跑,已經廢棄,請使用 {@link GM.Cat#startRun} 方法代替 * @removed */ run:function(){ this.bRun = true; }, /** * @method startRun 開始奔跑 * @return {Boolean} 開始奔跑是否成功 */ startRun:function(){ if(this.bRun === true){ return false; } this.bRun = true; return true; }, /** * @method playWithDog 與小狗一塊兒玩耍 * @param {GM.Dog} pDog 小狗 */ playWithDog:function(pDog){ this.player = pDog; } });
類 GM.Cat 派生自GM.Animal ,其中須要強調的有如下幾點:
*``` *示例: *var pCat = new GM.Cat({ * name:"Kity", * age:1, * sex:"女" *}) *```
這段註釋是描述了一個使用該類的示例,使用的是markdown語法來註釋的。在文字的首尾分別添加符號 "`
" 就能夠代表註釋代碼,可是注意該符號必定要換行使用,不然沒法生效。
/** * @event say 發出叫聲 * @param {GM.Cat} this 當前實例 * @param {String} value 叫聲 */ this.fireEvent("say", this, value);
這段註釋代表,類 GM.Cat 擁有一個名稱爲 「say」 的事件,該事件有兩個參數,一個是當前實例,另一個是字符串類型的叫聲。
* @property {"男"/"女"} configs.sex 性別 * @property {GM.Enum.Sex} props.sex 性別
上面代碼是描述枚舉的兩種方式。
dog.js代碼和cat.js代碼基本一致,這裏就再也不多作累述了。
至此,咱們全部的代碼構建工做就結束了,整個代碼結構以下圖所示
接下來,就是最後一步了——使用工具生成文檔。
咱們在與代碼同級的目錄下,建立一個 jsduck.json 配置文件,以便工具使用。配置文件內容以下:
{ "--title": "我是一個示例文檔", "--welcome": "welcome.html", "--warnings": ["-link", "-no_doc"], "--seo": true, "--": [ "./code" ], "--output": "./docs", "--examples-base-url": "../examples", "--examples": "./examples.json", "--body-html": [ "<script type='text/javascript'>", "Docs.otherProducts = [", "{text: 'Docs 3.0', href: 'http://***/3.0'},", "{text: 'Docs 2.0', href: 'http://***/2.0'},", "{text: 'Docs 1.0', href: 'http://***/1.0'}", "];", "</script>" ], "--categories":"./categories.json" }
咱們配置輸入文件爲整個代碼文件夾,解析全部代碼並生成文檔。這裏,咱們配置了一個 examples.json 文件做爲示例配置文件,文件內容以下:
[ { "title": "樣例展現", "items": [ { "name": "test-example", "title": "cat類使用示例", "description": "cat類使用示例", "url": "/example.html", "icon": "user.png", "status": "updated" } ] } ]
這裏,咱們配置了 examples 目錄下的 example.html 文件做爲示例頁面。
而後,裏面還配置了一個 categories.json 文件做爲代碼分類配置,文件內容以下:
[ { "name": "Common", "groups": [ { "name": "Base", "classes": [ "GM.Class", "GM.Util" ] }, { "name": "Animal", "classes": [ "GM.Animal", "GM.Cat", "GM.Dog" ] } ] } ]
該配置將代碼中的類分爲了兩組:Base 和 Animal 。這裏須要注意,JSDuck中代碼分類配置限制死了,只能配三級結構,不能作其餘級別的配置。
好啦!至此,全部的準備工做就所有完成啦!
此時,咱們只須要在 jsduck.json 目錄下,輕輕地輸入命令 jsduck
,就能夠看到隨着命令執行的結束,同級目錄下生成了一個 docs文件夾。這個文件夾就是咱們的文檔成果,進入該文件夾,打開頁面 template.html ,就能夠看到咱們今天的勞動成果啦!
曬一張成果圖,與你們共勉:
關於JSDuck的學習和實踐的分享,到這裏就告一段落啦。但願對你們有所幫助,也隨時歡迎你們和筆者討論相關技術。
全部源碼下載地址:https://pan.baidu.com/s/1dE88lPZ
歡迎關注個人微信公衆號: