摘要:目前進(jìn)化至版本了。該路由模塊是自動啟動的。此時該緩存并沒有被使用,的實例并沒有建立。所有的實例都是由內(nèi)部構(gòu)造器實例化而來的。三混合其他數(shù)據(jù)和屬性到當(dāng)前上四更新視圖,刪除傳導(dǎo)屬性,重置事件。另外,注意是很特殊的,在混入時會自動執(zhí)行。
riotjs
riotjs一款小型的10000star mvp框架。目前進(jìn)化至3.x版本了。讀者注意,本篇文章介紹的是2.2.4哦。為啥介紹這款啊,是因為那個啥,preact面向現(xiàn)代瀏覽器,對我來說不咋好使。
riotjs從出生到現(xiàn)在總共經(jīng)歷了3個大版本,基本上每個都不一樣,1.x最為簡陋,可以視之就一個簡單的mvc框架哦,模板引擎也是簡單的不要不要的,2.x版本完善了各項功能,并且強(qiáng)化了controller的作用,使之成為一個真正的MVP框架。3.x版本使用了大量es6,es5新增方法進(jìn)行重構(gòu),對svg支持,模板引擎,事件系統(tǒng),內(nèi)存使用等進(jìn)行了一定程度的優(yōu)化。(實際從2.3開始就往現(xiàn)代瀏覽器上靠了)
為何選用由于riotjs小,容易和其他框架混合使用
特點(diǎn)小,但經(jīng)不起強(qiáng)渲染
支持ie8嗎riotjs 2.2.4是最后一個支持ie8的版本。(然而事實上,代碼中使用了一些es5新增的方法,這些方法要ie9才支持,以至于我們不得不使用es5shiv/es5sham來進(jìn)行兼容);
靜態(tài)方法 riot.observableriot的事件系統(tǒng),所有事件通知方式都基于該模塊,可全局使用
// 發(fā)送全局事件 var window.eventBus = riot.observable(); eventBus.on("test", function (e) { console.log(e); }); eventBus.trigger("test", 123);
包含方法
on(events, fn)
off(events, fn)
trigger(name[,arguments])
one(name, fn)
riot.mixin作用是向內(nèi)部對象mixins添加屬性或方法,該對象無保護(hù),所以必須要人為保證命名時不沖突.
// 在外部使用 riot.mixin("testfunction", function () { console.log(2) }); var c = riot.mixin("testfunction"); c() // print 2
該方法一般提供給riot tag初始化實例的時候使用。當(dāng)在tag類中使用this.mixin混入方法的時候,會將內(nèi)部對象mixins上的方法或?qū)傩曰旌系絫ag類上
riot.route2.2.4版本的riot.route是一個功能超弱的路由管理器,通過監(jiān)聽hashchange事件來觸發(fā)注冊的路由回調(diào)。該路由模塊是自動啟動的。而且它的實現(xiàn)上是有缺陷的。它本質(zhì)上是個事件分發(fā)器。
// 使用示例 riot.route(function (path, module, action, params) { console.log(path, module, action, params) }); riot.route("search/index/search/1234");
包含方法
riot.route(arg)
2.2.4版本里arg接受2種類型,字符串和function,上面已經(jīng)給出示例。需要自己去分出路徑,模塊,行為和參數(shù)。你沒看錯,就是這么弱
riot.route.exec(fn)
解釋當(dāng)前哈希路徑,并把參數(shù)傳遞到fn里
riot.route.parser(fn)
指定哈希路徑解釋器,如果未調(diào)用該方法,固定解釋方法是 path.split("/");如示例所示
riot.route.stop()
銷毀監(jiān)聽hashchange事件,銷毀路由事件
riot.route.start()
監(jiān)聽。默認(rèn)是開啟的
riot.util包含兩個內(nèi)容,brackets和tmpl, brackets是tmpl的輔助函數(shù),多帶帶使用意義不大,該輔助函數(shù)可以通過正則或者索引制造我們需要匹配的部分。tmpl是riotjs的模板引擎核心,html字符串拼接完全通過該引擎,可獨(dú)立使用(在npm上有獨(dú)立維護(hù)的模塊名為riot-tmpl)
// 設(shè)置模板占位符(默認(rèn)是{ }) riot.settings.brackets = "{{ }}"; // 使用 var html = riot.util.tmpl("riot.tag(name, html, css, attrs, fn){{a}}", { a:1 }); console.log(html); //print1
全局注冊一個riot標(biāo)簽, css attrs參數(shù)可省略。其實質(zhì)是向一個內(nèi)部對象tagImpl上創(chuàng)建了一個名為name的屬性,其值是{name,html,css,attrs,fn}。此時該緩存并沒有被使用,tag的實例并沒有建立。
riot.tag( "ri-root", [ "riot.mount & riot.mountTo", " " ].join(""), function () { var self = this; this.showLogin = false; this.showError = false; this.on("mount", function () { var device_id = window.Qutils.getParams("device_id"); if (!device_id) { alert("參數(shù)device_id缺失!"); } else { setTimeout(function () { bridge.isInApp( function () { self.showLogin = true; self.tags["ri-login"].trigger("login-init", device_id); self.update(); }, function () { self.showError = true; self.update(); } ) }, 100); } }); } );
riot.mountTo只是riot.mount的別名。該方法顧名思義,掛在riot標(biāo)簽(組件)。會返回一個tag的實例。
參數(shù)
selector
接受"*"(mount所有), string split with "," , string(使用原生的Selectors API,獲取一個NodeList),或者接受一個NodeList,Element
tagName
接受"*"(mount所有), object(當(dāng)為Object類型時,即為opts),string(等同mount所有selector上下文下的tagName匹配tag)
opts
Object,傳入的參數(shù)對象,可直接混合在tag實體的opts對象上
riot.update
更新所有的tag實體,實質(zhì)是調(diào)用每個實體的update方法。
riot的tag實例方法上文說到riot中所用通過riot.tag聲明的custom tag都只是緩存了,而沒有立刻產(chǎn)生tag實例。實際上tag實例是在執(zhí)行riot.mount的時候被創(chuàng)建的。所有的riot tag實例都是由內(nèi)部構(gòu)造器Tag實例化而來的。而對于一個多tag嵌套的組件,其實是遞歸先將子tag從底部實例化完,當(dāng)實例化完成,會從根部到底部依次觸發(fā)mount事件~
this.isMountedtrue | false, 指示tag是否完成安裝
this._id一個自增的id,用于唯一代表該實例
this.parent若一個tag實例有父實例,這個parent指向父實例
this.on("mount", function () { this.parent && this.parent.trigger("child-mounted"); }.bind(this))this.root
該屬性指向tag實例所表示的真實dom元素,另外root._tag同樣掛載了tag實例的引用,所以當(dāng)你的個自定義標(biāo)簽實例化以后,你還可以通過這樣的姿勢找到tag實例
var tag = riot.mount("custom-tag"); console.log(tag[0].root); // printthis.optsconsole.log(document.querySelector("custom-tag")._tag) // print Tag {xxx}
哦,這個的構(gòu)造器是Child,不過特的原型指向你傳入的opts的引用。所以如果不想自己配置被改動,請乖乖深度克隆
var tag = riot.mount("custom-tag", {a:1,b:2,c:3}); console.log(tag[0].opts.a); // print 1
另外如果要在父子tag間傳遞參數(shù)也是很好玩的.
riot.tag( "hhh", "", function () {} ); riot.tag( "zzz", " {this.opts.myoptions}", function () {} ); var new_custom_tag = document.createElement("hhh"); document.body.appendChild(new_custom_tag); var custom_tag = riot.mount("hhh", {test:1}); console.log(custom_tag[0].tags["zzz"].opts.myoptions); // print: 1
// 注: riot沒有state機(jī)制,要通過attributes傳值,小心undefined
需要注意的是,由于他遍歷的是dom.attributes,你玩表單的時候小心一點(diǎn)。
this.tags這里面放了子tag的實例的引用,上面的示例中有類似用法。多個同名子tag會放在數(shù)組里,我記不得在哪個版本里了,即使是一個子tag也會放在數(shù)組里。
this.update(data)這個操作分為幾個步驟:
一:源碼里明確寫到,執(zhí)行該方法先判斷data對象里有沒有可能覆蓋tag實例屬性的屬性,如果有,丟棄。注意,該處過濾數(shù)據(jù)使用的是淺復(fù)制,如果是對象套對象,你要小心了。
二:如果是循環(huán)產(chǎn)生的tag(注意,如果不是在custom-tag上使用each循環(huán)產(chǎn)生,不會去繼承,因為此時isLoop為undefined),重新從父tag獲取需要繼承的值
riot.tag( "hhh", "", function () { this.eee = [{a:1,b:2},{a:1,b:2}]; this.eeeeeeeeee = 43214321; this.fdsafsdf = 3253425432 } ); riot.tag( "zzz", " {a}", function () { this.fffff = 4325345342543} ); var new_custom_tag = document.createElement("hhh"); document.body.appendChild(new_custom_tag); var custom_tag = riot.mount("hhh", {test:1}); console.log(custom_tag[0].tags.zzz[0].fdsafsdf) // print 3253425432
riot.tag( "hhh", "", function () { this.eee = [{a:1,b:2},{a:1,b:2}]; this.eeeeeeeeee = 43214321; this.fdsafsdf = 3253425432 } ); riot.tag( "zzz", "{a}", function () { this.fffff = 4325345342543} ); var new_custom_tag = document.createElement("hhh"); document.body.appendChild(new_custom_tag); var custom_tag = riot.mount("hhh", {test:1}); console.log(custom_tag[0].tags.zzz[0].fdsafsdf) // print undefined
該特性可能會對您造成困擾,啥時候誤操作都可能一頭霧水不造為什么。
三:混合其他數(shù)據(jù)和屬性到當(dāng)前tag上
四:更新視圖,刪除dom傳導(dǎo)屬性,重置事件。(所以說如果你瀏覽器在dom回收和事件回收上有問題,那你更新的時候就相當(dāng)捉急了,在最新的版本里把這個泄漏點(diǎn)給堵上了)
this.mixin()接受無數(shù)多個字符串參數(shù),內(nèi)部運(yùn)行 riot.mixin[arguments[i]]將需要混入的屬性或方法混入到實例上~~前面介紹過了。在2.2.4以前的版本沒有使用.bind(this)來參入作用域,略蛋疼的說,2.2.4 對混入的方法都bind了當(dāng)前作用域。另外,注意init是很特殊的,在混入時會自動執(zhí)行。
riot.mixin({ init: function () { this.a = 1; console.log("init") } }); riot.tag("test", "", function () { this.mixin("init"); }); var a = document.createElement("test"); document.body.appendChild(a); var custom_tag = riot.mount("test"); console.log(custom_tag[0].a) // print 1this.mount()
將該實例強(qiáng)制重新裝載一遍
this.unmount(keepRootTag)傳入?yún)?shù),如果為true,會把初始化用的那個根節(jié)點(diǎn)也刪球掉。該方法用于卸載實例,釋放內(nèi)存。
on, off, trigger, one通過riot.observable混入的事件方法,然后我們可以在不同tag實例上到處傳播事件了,建議使用一個集線器把事件管理起來,或者使用其他玩意,比如riot-flux什么的來玩。
生命周期to be continue
后記這個框架跟虛擬dom沒撒關(guān)系,因為完全沒有diff算法。。。在更新視圖的時候用了文檔碎片湊~,效果還湊合
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81816.html
摘要:列表的樂趣標(biāo)簽空格分隔文章的原文是刪除元素所有等于值的元素重復(fù)警告該方法不負(fù)責(zé)列表項的順序。 列表的樂趣 標(biāo)簽(空格分隔): Python list 文章的原文是 Fun with Lists 1 刪除元素 1.1 所有等于 X 值的元素 x = 4 a = [1, 2, 3, 4, 4, 5, 6, 1, 4] for i in range(a.count...
摘要:工具安裝使用示例問題下面兩部分的順序不能交換第一個參數(shù)是空數(shù)組故意寫錯答案,展示測試失敗輸出效果測試用例編寫說明要測試的都是函數(shù),參數(shù)個數(shù)不定,但返回值是一個。上面例子的輸入?yún)?shù)是,第一個參數(shù)是數(shù)組,第二個參數(shù)是數(shù)值返回值是一個數(shù)組。 描述 最近在用es6解leetcode,當(dāng)問題比較復(fù)雜時,有可能修正了新的錯誤,卻影響了前面的流程。要用通用的測試工具,卻又有殺雞用牛刀的感覺,所以就寫...
閱讀 781·2023-04-25 16:55
閱讀 2821·2021-10-11 10:59
閱讀 2086·2021-09-09 11:38
閱讀 1799·2021-09-03 10:40
閱讀 1495·2019-08-30 15:52
閱讀 1134·2019-08-30 15:52
閱讀 965·2019-08-29 15:33
閱讀 3505·2019-08-29 11:26