2018年首個計劃是學習vue源碼,查閱了一番資料之后,決定從第一個commit開始看起,這將是一場持久戰!本篇介紹directive的簡單實現,主要學習其實現的思路及代碼的設計(directive和filter擴展起來非常方便,符合設計模式中的 開閉原則 )。
構思API
<div id="app" sd-on-click="toggle | .button"> <p sd-text="msg | capitalize"></p> <p sd-class-red="error" sd-text="content"></p> <button class="button">Toggle class</button></div>var app = Seed.create({ id: 'app', scope: { msg: 'hello', content: 'world', error: true, toggle: function() { app.scope.error = !app.scope.error; } }});實現功能夠簡單吧--將scope中的數據綁定到app中。
核心邏輯設計
指令格式
以 sd-text="msg | capitalize" 為例說明:
其中 | 后面為過濾器,可以添加多個。 sd-class-red 中的red為參數。
代碼結構介紹
main.js 入口文件
// Seed構造函數const Seed = function(opts) {};// 對外暴露的APImodule.exports = { create: function(opts) { return new Seed(opts); }};directives.jsmodule.exports = { text: function(el, value) { el.textContent = value || ''; }};filters.jsmodule.exports = { capitalize: function(value) { value = value.toString(); return value.charAt(0).toUpperCase() + value.slice(1); }};就這三個文件,其中directives和filters都是配置文件,很易于擴展。
實現的大致思路如下:
1.在Seed實例創建的時候會依次解析el容器中node節點的指令
2.將指令解析結果封裝為指令對象,結構為:
| 屬性 | 說明 | 類型 |
|---|---|---|
| attr | 原始屬性,如 sd-text | String |
| key | 對應scope對象中的屬性名稱 | String |
| filters | 過濾器名稱列表 | Array |
| definition | 該指令的定義,如text對應的函數 | Function |
| argument | 從attr中解析出來的參數(只支持一個參數) | String |
| update | 更新directive時調用 typeof def === 'function' ? def : def.update | Function |
| bind | 如果directive中定義了bind方法,則在 bindDirective 中會調用 | Function |
| el | 存儲當前element元素 | Element |
新聞熱點
疑難解答
圖片精選