Commit 5: dump, destroy, fix filters
- 主要改动:添加了一个大写的过滤器
Commit 4: filter value should not be written
- 主要改动:
- 将
bindings
变量改为原型属性_bindings
- 增加了2个Seed的原型方法
- dump():复制一份bindings
- destroy():移除el上的事件
- 当需要过滤时,仍保存之前的值(之前会直接用过滤后的值覆盖掉原来的赋值)
- 将
Commit 3: naive implementation
主要改动:实现了
sd-
前缀的指令(sd-text
、sd-show
、sd-class
、sd-on
)-
怎么使用?
具体思路与现在现在的 Vue 相差并不多,示例(就是dev.html):
<div id="test" sd-on-click="changeMessage | .button"> <p sd-text="msg | capitalize"></p> <p sd-show="something">YOYOYO</p> <p class="button" sd-text="msg"></p> <p sd-class-red="error" sd-text="hello"></p> </div>
var Seed = require('seed') var app = Seed.create({ id: 'test', // template scope: { msg: 'hello', hello: 'WHWHWHW', changeMessage: function () { app.scope.msg = 'hola' } } })
用过 Vue 的人一定会觉得这个模式很熟悉,比如
sd-text
可以对应v-text
。当我们知道这个指令有什么功能后,再去思考如何实现这个功能就会比较简单。因此虽然已经有点久远,但是还是推荐每个commit都对应着官网的文档看。 -
原理:
- 思路与commit2类似。将页面中需要的变量如(msg),以及这个变量控制哪个节点、该变量发生改变时节点需要进行什么变化等等存储在bindings中。
- 给Seed实例中的响应属性修改get、set,使其与bindins连接起来
-
dev.html
的执行过程 -
总结
Commit 2: rename
主要改动:实现了诸如
{{ msg }}
形式的模板语法-
原理:
- 页面和对象通过bindings联系
- 通过set实现自动修改
-
代码实现
-
getset.html
<!DOCTYPE html> <html> <head> <title>ideal</title> <meta charset="utf-8"> </head> <body> <div id="test"> <p>{{msg}}</p> <p>{{msg}}</p> <p>{{msg}}</p> <p>{{what}}</p> <p>{{hey}}</p> </div> <script> var bindingMark = 'data-element-binding' function Element (id, initData) { var self = this, el = self.el = document.getElementById(id) bindings = {} // the internal copy data = self.data = {} // the external interface /* 相关步骤:1.b 把{{msg}}这种形式替换成<span data-element-binding="msg"></span> */ content = el.innerHTML.replace(/\{\{(.*)\}\}/g, markToken) el.innerHTML = content for (var variable in bindings) { bind(variable) } /* 相关步骤:3 */ if (initData) { for (var variable in initData) { /* 修改属性后页面就会自动更新了 */ data[variable] = initData[variable] } } function markToken (match, variable) { /* 相关步骤:1.a 对于每个匹配到的变量(msg、what、hey),都给bindings加上相应的属性 */ bindings[variable] = {} return '<span ' + bindingMark + '="' + variable +'"></span>' } function bind (variable) { /* 相关步骤:2.a 找到msg、what、hey分别对应哪些节点,保存在相应的els中 */ bindings[variable].els = el.querySelectorAll('[' + bindingMark + '="' + variable + '"]') /* 相关步骤:2.b 清除'data-element-binding',只留下<p><span></span></p>这种形式 */ ;[].forEach.call(bindings[variable].els, function (e) { e.removeAttribute(bindingMark) }) /* 相关步骤:2.c 给app.data添加属性(msg、what、hey) 当修改属性值时,会自动修改每个相关节点的内容 以及bindings中的值 */ Object.defineProperty(data, variable, { set: function (newVal) { [].forEach.call(bindings[variable].els, function (e) { bindings[variable].value = e.textContent = newVal }) }, get: function () { return bindings[variable].value } }) } } var app = new Element('test', { msg: 'hello' }) </script> </body> </html>
-
Commit 1: initial setup
主要改动:初始化
备注:代码中有很多配置文件,其中很多是比较旧的工具了,所以这一部分不做深入研究了