xwjie / VueStudyNote

vue学习笔记

Home Page:https://xwjie.github.io/VueStudyNote/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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>