摘要:目前进化至版本了。该路由模块是自动启动的。此时该缓存并没有被使用,的实例并没有建立。所有的实例都是由内部构造器实例化而来的。三混合其他数据和属性到当前上四更新视图,删除传导属性,重置事件。另外,注意是很特殊的,在混入时会自动执行。
riotjs
riotjs一款小型的10000star mvp框架。目前进化至3.x版本了。读者注意,本篇文章介绍的是2.2.4哦。为啥介绍这款啊,是因为那个啥,preact面向现代浏览器,对我来说不咋好使。
riotjs从出生到现在总共经历了3个大版本,基本上每个都不一样,1.x最为简陋,可以视之就一个简单的mvc框架哦,模板引擎也是简单的不要不要的,2.x版本完善了各项功能,并且强化了controller的作用,使之成为一个真正的MVP框架。3.x版本使用了大量es6,es5新增方法进行重构,对svg支持,模板引擎,事件系统,内存使用等进行了一定程度的优化。(实际从2.3开始就往现代浏览器上靠了)
为何选用由于riotjs小,容易和其他框架混合使用
特点小,但经不起强渲染
支持ie8吗riotjs 2.2.4是最后一个支持ie8的版本。(然而事实上,代码中使用了一些es5新增的方法,这些方法要ie9才支持,以至于我们不得不使用es5shiv/es5sham来进行兼容);
静态方法 riot.observableriot的事件系统,所有事件通知方式都基于该模块,可全局使用
// 发送全局事件 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作用是向内部对象mixins添加属性或方法,该对象无保护,所以必须要人为保证命名时不冲突.
// 在外部使用 riot.mixin("testfunction", function () { console.log(2) }); var c = riot.mixin("testfunction"); c() // print 2
该方法一般提供给riot tag初始化实例的时候使用。当在tag类中使用this.mixin混入方法的时候,会将内部对象mixins上的方法或属性混合到tag类上
riot.route2.2.4版本的riot.route是一个功能超弱的路由管理器,通过监听hashchange事件来触发注册的路由回调。该路由模块是自动启动的。而且它的实现上是有缺陷的。它本质上是个事件分发器。
// 使用示例 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,上面已经给出示例。需要自己去分出路径,模块,行为和参数。你没看错,就是这么弱
riot.route.exec(fn)
解释当前哈希路径,并把参数传递到fn里
riot.route.parser(fn)
指定哈希路径解释器,如果未调用该方法,固定解释方法是 path.split("/");如示例所示
riot.route.stop()
销毁监听hashchange事件,销毁路由事件
riot.route.start()
监听。默认是开启的
riot.util包含两个内容,brackets和tmpl, brackets是tmpl的辅助函数,多带带使用意义不大,该辅助函数可以通过正则或者索引制造我们需要匹配的部分。tmpl是riotjs的模板引擎核心,html字符串拼接完全通过该引擎,可独立使用(在npm上有独立维护的模块名为riot-tmpl)
// 设置模板占位符(默认是{ }) riot.settings.brackets = "{{ }}"; // 使用 var html = riot.util.tmpl("riot.tag(name, html, css, attrs, fn){{a}}", { a:1 }); console.log(html); //print1
全局注册一个riot标签, css attrs参数可省略。其实质是向一个内部对象tagImpl上创建了一个名为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("参数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标签(组件)。会返回一个tag的实例。
参数
selector
接受"*"(mount所有), string split with "," , string(使用原生的Selectors API,获取一个NodeList),或者接受一个NodeList,Element
tagName
接受"*"(mount所有), object(当为Object类型时,即为opts),string(等同mount所有selector上下文下的tagName匹配tag)
opts
Object,传入的参数对象,可直接混合在tag实体的opts对象上
riot.update
更新所有的tag实体,实质是调用每个实体的update方法。
riot的tag实例方法上文说到riot中所用通过riot.tag声明的custom tag都只是缓存了,而没有立刻产生tag实例。实际上tag实例是在执行riot.mount的时候被创建的。所有的riot tag实例都是由内部构造器Tag实例化而来的。而对于一个多tag嵌套的组件,其实是递归先将子tag从底部实例化完,当实例化完成,会从根部到底部依次触发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实例的引用,所以当你的个自定义标签实例化以后,你还可以通过这样的姿势找到tag实例
var tag = riot.mount("custom-tag"); console.log(tag[0].root); // printthis.optsconsole.log(document.querySelector("custom-tag")._tag) // print Tag {xxx}
哦,这个的构造器是Child,不过特的原型指向你传入的opts的引用。所以如果不想自己配置被改动,请乖乖深度克隆
var tag = riot.mount("custom-tag", {a:1,b:2,c:3}); console.log(tag[0].opts.a); // print 1
另外如果要在父子tag间传递参数也是很好玩的.
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机制,要通过attributes传值,小心undefined
需要注意的是,由于他遍历的是dom.attributes,你玩表单的时候小心一点。
this.tags这里面放了子tag的实例的引用,上面的示例中有类似用法。多个同名子tag会放在数组里,我记不得在哪个版本里了,即使是一个子tag也会放在数组里。
this.update(data)这个操作分为几个步骤:
一:源码里明确写到,执行该方法先判断data对象里有没有可能覆盖tag实例属性的属性,如果有,丢弃。注意,该处过滤数据使用的是浅复制,如果是对象套对象,你要小心了。
二:如果是循环产生的tag(注意,如果不是在custom-tag上使用each循环产生,不会去继承,因为此时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} {b}", 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} {b}", 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
该特性可能会对您造成困扰,啥时候误操作都可能一头雾水不造为什么。
三:混合其他数据和属性到当前tag上
四:更新视图,删除dom传导属性,重置事件。(所以说如果你浏览器在dom回收和事件回收上有问题,那你更新的时候就相当捉急了,在最新的版本里把这个泄漏点给堵上了)
this.mixin()接受无数多个字符串参数,内部运行 riot.mixin[arguments[i]]将需要混入的属性或方法混入到实例上~~前面介绍过了。在2.2.4以前的版本没有使用.bind(this)来参入作用域,略蛋疼的说,2.2.4 对混入的方法都bind了当前作用域。另外,注意init是很特殊的,在混入时会自动执行。
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()
将该实例强制重新装载一遍
this.unmount(keepRootTag)传入参数,如果为true,会把初始化用的那个根节点也删球掉。该方法用于卸载实例,释放内存。
on, off, trigger, one通过riot.observable混入的事件方法,然后我们可以在不同tag实例上到处传播事件了,建议使用一个集线器把事件管理起来,或者使用其他玩意,比如riot-flux什么的来玩。
生命周期to be continue
后记这个框架跟虚拟dom没撒关系,因为完全没有diff算法。。。在更新视图的时候用了文档碎片凑~,效果还凑合
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/81816.html
摘要:列表的乐趣标签空格分隔文章的原文是删除元素所有等于值的元素重复警告该方法不负责列表项的顺序。 列表的乐趣 标签(空格分隔): 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...
摘要:工具安装使用示例问题下面两部分的顺序不能交换第一个参数是空数组故意写错答案,展示测试失败输出效果测试用例编写说明要测试的都是函数,参数个数不定,但返回值是一个。上面例子的输入参数是,第一个参数是数组,第二个参数是数值返回值是一个数组。 描述 最近在用es6解leetcode,当问题比较复杂时,有可能修正了新的错误,却影响了前面的流程。要用通用的测试工具,却又有杀鸡用牛刀的感觉,所以就写...
阅读 730·2023-04-25 16:55
阅读 2783·2021-10-11 10:59
阅读 2051·2021-09-09 11:38
阅读 1757·2021-09-03 10:40
阅读 1466·2019-08-30 15:52
阅读 1075·2019-08-30 15:52
阅读 917·2019-08-29 15:33
阅读 3434·2019-08-29 11:26