仿照vue实现简易的MVVM框架(三)

前两次写的都实现了MVVM框架的一些基本功能,包括双向绑定、v-text、v-for、v-show、v-if 、插值等功能,这一节主要是实现绑定事件的功能。

首先,使用methods存储所有的事件,节点对象增加event属性,是用来存储事件的数组,这里需要使用正则去匹配'@'或者'v-on:',取出事件类型以及事件名称,注意这里需要用bind绑定执行环境,代码如下:

var attributes = node.attributes;
attributes = [].slice.call(attributes);
var reg = /(@)|(s-on:)/g;
temp.event = [];
for (var i = 0; i < attributes.length; i++) {
	if (reg.test(attributes[i].name)) {
		var len = attributes[i].name.match(reg)[0].length;
		var type = attributes[i].name.substring(len);
		temp.event.push({type: type, event: attributes[i].value});
	}
}

在render函数中:

if (item.event) {
	for (var i = 0; i < item.event.length; i++) {
		//console.log(methods[item.event[i].event]);
		item.node.addEventListener(item.event[i].type, that.eventProcess(methods[item.event[i].event]), false);
	}
}

this.eventProcess = function(fn) {
	return fn.bind(oop);
}

还需要注意的是,循环模版中,因为改变了dom结构,所以里面如果有绑定的事件需要重新绑定一次:

case 's-for':
var items = data[item.list];
var fragment = document.createDocumentFragment();
if (content) {
	for (var i = 0, len = items.length; i < len; i++) {
		var dom = document.createElement(item.node
			.nodeName.toLowerCase());
		dom.innerHTML = items[i][content];
		_if (item.event) {
			for (var j = 0; j < item.event.length; j++) {
				dom.addEventListener(item.event[j].type, that.eventProcess(methods[item.event[j].event]), false);
			}
		}_
		fragment.appendChild(dom);
	}
	if (item.parentNode) {
		var dom = document.createElement(item.node
			.nodeName.toLowerCase());
		item.parentNode.innerHTML = '';
		item.parentNode.appendChild(fragment);
	} else{
		if (item.nextElementSibling === undefined) {
			item.nextElementSibling = item.node.nextElementSibling;
			if (item.node.nextElementSibling === null) {
				item.node.parentNode.insertBefore(fragment, item.node);
				//console.log(item.node.parentNode.lastElementChild);
				item.node.parentNode.removeChild(item.node.parentNode.lastElementChild);
			} else { 
				item.node.nextElementSibling.parentNode.insertBefore(fragment, item.node);
				item.node.nextElementSibling.parentNode.removeChild(item.node);
			}
		}
	}
}
break;

至此,就实现了基本绑定事件,这时候,这个对象里存储的东西预览一下:

好嘞,算完工吧!

原文地址:https://www.cnblogs.com/susantong/p/6963466.html