13 实现bind指令
xwjie opened this issue · comments
就是vue里面的v-bind
数据绑定,缩写为 :
。简单起见,我们只用缩写。
实现
实现很简单,修改生成render函数字符串的代码。就是解析的时候,如果发现是 :
开头的属性,就把它解析为表达式,否则就是字符串。就是这么简单。
/**
* 解析属性
* @param {*} node
*/
function genAttrStr(node: any) {
let attrs = node.attrsMap
let str = '';
if (attrs) {
str += 'props:{'
// why not use for..in, see eslint `no-restricted-syntax`
Object.keys(attrs).forEach(attrname => {
// 如果是数据绑定,则后面的是表达式
if (attrname.charAt(0) == ':') {
str += JSON.stringify(attrname.substr(1)) + ':' + attrs[attrname] + ','
}
else {
str += JSON.stringify(attrname) + ':' + JSON.stringify(attrs[attrname]) + ','
}
})
str += '},'
}
return str;
}
class属性要单独处理
/**
* 得到带类名的TAG名
*
* 返回如 “div.classes” (静态) 或者 “div." + nowClass (动态)
*
* TODO : 没有支持id和多class 如 'div#container.two.classes'
*
*/
function getTagAndClassName(node: any) {
let tag = JSON.stringify(node.tag)
let attrs = node.attrsMap
if (!attrs) {
return tag
}
//FIXME 大小写有bug
// 如果有class属性
let v = attrs['class']
if (v) {
return JSON.stringify(node.tag + '.' + v)
}
// 如果有动态绑定的class属性
v = attrs[':class']
if (v) {
return JSON.stringify(node.tag + '.') + '+' + v
}
return tag
}
测试代码
<!DOCTYPE html>
<html>
<head>
<title>Xiao框架之helloworld</title>
<script src="../dist/xiao.js"></script>
<style>
.c1 {
color: blue;
}
.c2 {
color: red;
}
</style>
</head>
<body>
<h1>bind指令测试</h1>
<div id="demo1">
<input :value="value" :class="nowClass"/><br/>
<input value="this is a string value" class="c1"/>
</div>
<script>
var app = new Xiao({
data:{
value: "这里变量",
nowClass: "c2"
}
});
app.$mount("#demo1");
setTimeout(function(){
app.value = "修改了数据";
app.nowClass = "c1"
}, 1000);
</script>
</body>
</html>