@Wahson
2017-05-08T15:04:07.000000Z
字数 1399
阅读 1188
前端技术
需求依然非常简单,实现一个跟Vue.js差不多的框架就行。
那么既然这样,还是先看一个Polymer的痛点:
<div>{{ parseNum(floatNum) }}</div>
<div>{{ reverseStr(str) }}</div>
class XElem extends Polymer.Element {
...
static get properties(){
return {
floatNum:{
type:Number,
value:"10.001"
},
str:{
type:String,
value:"abcedfg"
},
total:{
type:Number,
value:666
}
};
}
parseNum(num){
return parseInt(num);
}
reverseStr(str){
return str.split('').reverse().join('');
}
}
以上代码实现的功能非常简单,把一个浮点数转成整数显示在页面上,另外把一个字符串逆序后显示。上面是Polymer典型的实现,这里我们要为每一个需要处理的属性(floatNum,str)分别定义处理方法(parseNum,reverseStr),即便是非常简单的操作。经验告诉我们,大部分这些处理方法定义后只使用一次。于是日复一日编写这样啰嗦繁琐的代码后,程序员的哀怨之声开始宁饶在办公室的上空。
于是我们有了Template-Expression的需求(Vue.js有的,Polymer大法也得有啊)
先来看一下Template-Expression 2.0特性的用法:
<div>{{{ parseInt(floatNum) }}}</div>
<div>{{{ str.split('').reverse().join('') }}}</div>
<div>{{{ floatNum + floatNum + 1 }}}</div>
用法非常简单:
{{{
doSthWith(propertyName)}}}
原理解析:
其实这个用法不过是一个语法糖。我们以{{{ parseInt(floatNum) }}}
这个表达式为例来浅谈一下这个sugar。
其实这个语法糖逆转过来,完全等同于以下写法
<div>{{ tmplFn_1494252916934_9013(total) }}</div>
class XElem extends Polymer.Element {
...
tmplFn_1494252916934_9013(_var1494254257038_395_) {
return parseInt(_var1494254257038_395_);
}
}
表达式会被重新解析,里面的属性变量(total
)会被重命名(_var1494254257038_395_
),而后表达式会作为一个新函数(tmplFn_1494252916934_9013
)的返回结果,接着这个新的函数会被添加到XElem的prototype原型上。当然,还会对total
进行双向绑定。
Template-Expression特性相关代码:
https://github.com/mrLeung/polymer/commit/8b9ea2380b29184535943352d2a0e5abab6fbbda
核心代码函数_parseTemplateExpression