摘要:是一個輕巧的框架它實現了數據的雙向綁定并提供一些基本的指令幫助你提升效率,比如,,,,是的,如你所見,以開頭的指令是它的獨特標識行左右的代碼量,讓應用的開發和加載的一瞬完成倉庫指令往下看之前,請大家沐浴更衣,因為我要講的指令了中的已經被占用
BiuJS
BiuJS是一個輕巧的mvvm框架$指令
它實現了數據的雙向綁定
并提供一些基本的指令幫助你提升效率,比如$for,$model,$if,$click,$style
是的,如你所見,以$開頭的指令是它的獨特標識
1000行左右的代碼量,讓應用的開發和加載biu的一瞬完成
BiuJS倉庫: https://github.com/veedrin/biu
往下看之前,請大家沐浴更衣,因為我要講BiuJS的$指令了
{{vipName}}
JavaScript中的$已經被jQuery占用了,現在html標簽中的$也被BiuJS占用了
我已經為$指令申請了專利,是真的(假的)
Compiler.prototype.compileElement = function(ele) { let self = this; Array.from(ele.attributes).forEach((attr) => { let name = attr.name; let type; if (name.indexOf("$") === 0) { type = name; } else { return; } let exp = attr.value; let handler = self[type]; if (handler) { handler.call(self, ele, exp, self.vm); } ele.removeAttribute(name); }); };
因為每一個指令的編譯規則都是不一樣的,所以我們要提取出$指令,然后交給相應的函數處理
注意,handler需要用call方法調用,否則handler內部的this不會指向Compiler構造函數
$for編寫html的時候,我們經常會遇到DOM結構一樣但數據不一樣的情況
這時候如果有一個工具,能夠遍歷數據,然后插入到相應份拷貝的DOM結構中,簡直太好了
$for指令就是為這個而生的
我們先來看$for指令的用法
這里的item和index可以隨意更換成你順手的單詞,只需要記住item是總數據的一項,如果需要索引則要加一對括號
讓我們提取其中的表達式
let regIterate = /^(([w,s]+))/; let split = exp.split("in"); let expItem = split[0].trim(); let expList = split[1].trim(); let expIndex; if (regIterate.test(expItem)) { let match = regIterate.exec(expItem)[1]; split = match.split(","); expItem = split[0].trim(); expIndex = split[1].trim(); }
目前$for指令有一個缺陷,它需要用一層div包裹起來,雖然頁面效果是一樣的,但畢竟破壞了DOM結構。如果有好的解決方案,可以在文末留言
let divWrap = document.createElement("div"); ele.parentNode.insertBefore(divWrap, ele); ele.parentNode.removeChild(ele); ele.removeAttribute("$for"); let cloneOrigin = ele.cloneNode(true);
先插入一個div,然后把元素移除
這里需要克隆一個元素的副本,因為之后數據變更,我們要拿這個副本去重新編譯
因為子元素可能會(應該是一定會)使用帶有item和index的胡子模板
所以我們要把它們都替換成實際的值
let regItem = new RegExp(`{{${expItem}}}`, "g"); let regIndex = new RegExp(`{{${expIndex}}}`, "g"); if (child.nodeType === 3 && !regBlank.test(child.textContent)) { let content = child.textContent.trim(); let str = self.replace$for(content, item, regItem); if (expIndex) { str = self.replace$for(str, index, regIndex); } child.textContent = str; }
replace$for和文本編譯是差不多的,算是簡化版
Compiler.prototype.replace$for = function(content, value, reg) { let i = 0; let match; let text; let temp = ""; while (match = reg.exec(content)) { if (i < match.index) { text = content.slice(i, match.index); temp += text; } i = reg.lastIndex; temp += value; } if (i < content.length) { text = content.slice(i); temp += text; } return temp; };
但是到這里還沒完,因為$click指令有可能把item和index作為參數傳進自己的函數
而item和index并不在data里面,不能用execChain方法獲取實際的值
所以在這里一并把它給編譯了
let regCall = /((.*))$/; Array.from(child.attributes).forEach((attr) => { if (attr.name === "$click") { let exp = attr.value; let match = regCall.exec(exp); if (match) { let funcName = exp.slice(0, exp.indexOf("(")); if (match[1] === expItem) { attr.value = `${funcName}("${item}")`; } else if (match[1] === expIndex) { attr.value = `${funcName}("${index}")`; } } } });
最后是訂閱器的回調
做法就是先移除div里面的所有子元素,遍歷一下數據,看看新值有幾項,然后拿來副本,照上面相應的編譯幾次
new Watcher(exp, vm, (newValue) => { Array.from(divWrap.childNodes).forEach((child) => { divWrap.removeChild(child); }); newValue.forEach((item, index) => { let cloneNode = cloneOrigin.cloneNode(true); self.compile$for(cloneNode, expItem, item, expIndex, index); divWrap.appendChild(cloneNode); }); });寫在后面
以上就是編譯$for指令的過程
歡迎到BiuJS倉庫: https://github.com/veedrin/biu了解詳情
更歡迎Star和Fork
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90338.html
摘要:如此循環,直到結束如果循環結束之后,比字符串的長度要小,那說明后面還有文本匹配失敗了。 showImg(https://segmentfault.com/img/remote/1460000012478667?w=1920&h=926); BiuJS BiuJS是一個輕巧的mvvm框架它實現了數據的雙向綁定并提供一些基本的指令幫助你提升效率,比如$for,$model,$if,$cli...
摘要:是一個輕巧的框架它實現了數據的雙向綁定并提供一些基本的指令幫助你提升效率,比如,,,,是的,如你所見,以開頭的指令是它的獨特標識行左右的代碼量,讓應用的開發和加載的一瞬完成倉庫啟動首先我們來看一下是如何啟動的是的掛載點,它決定在多大范圍的樹 showImg(https://segmentfault.com/img/remote/1460000012478667?w=1920&h=926...
摘要:是一個輕巧的框架它實現了數據的雙向綁定并提供一些基本的指令幫助你提升效率,比如,,,,是的,如你所見,以開頭的指令是它的獨特標識行左右的代碼量,讓應用的開發和加載的一瞬完成倉庫訂閱清單前文說到提供了一個強大的接口我們就用它來劫持數據不過在此 showImg(https://segmentfault.com/img/remote/1460000012478667?w=1920&h=926...
摘要:本篇博客主要介紹了如何使用以及從零開始,創建屬于自己的命令行工具。一分鐘體驗首先我們先花一分鐘的時間,體驗一下創建自己的命令行工具是什么感覺。或者是一個環境下的命令行接口解決方案。代表了這個工具向用戶暴露的命令行指令。 本篇博客主要介紹了如何使用commander, inquirer以及chalk從零開始,創建屬于自己的命令行工具。 0. 一分鐘體驗 首先我們先花一分鐘的時間,體驗一下...
摘要:自動化打包上文章概述本文分為上下兩篇,上篇主要介紹一些常用的插件也是此次打包主要用的插件,而下篇主要以一個項目為例,從本地出合適的版本,壓縮合并到最后打成包,發送至指定目錄,做一個全面的演示。 gulp自動化打包(上) 文章概述 本文分為上下兩篇,上篇主要介紹一些常用的gulp插件(也是此次打包主要用的gulp插件),而下篇主要以一個demo項目為例,從本地checkout出合適的g...
閱讀 1598·2021-11-04 16:11
閱讀 3309·2021-09-09 11:33
閱讀 1558·2019-08-30 15:54
閱讀 619·2019-08-30 15:44
閱讀 3174·2019-08-30 15:43
閱讀 2554·2019-08-30 13:06
閱讀 1698·2019-08-29 17:00
閱讀 895·2019-08-29 15:33