一、模版解析之事件指令的分析
- 事件指令:在
vue
中是比较常见的, 比如v-on:click
等进行绑定点击事件。
- 模版解析之事件指令的实现过程:
- 从指令名中取出事件名
- 根据指令的值(表达式)从
methods
中得到对应的事件处理函数对象
- 给当前元素节点绑定指定事件名和回调函数的
dom
事件监听
- 指令解析完后, 移除此指令属性
- 模版解析之事件指令的关键过程:
compile: function (node) {
var nodeAttrs = node.attributes,
me = this;
[].slice.call(nodeAttrs).forEach(function (attr) {
var attrName = attr.name;
if (me.isDirective(attrName)) {
var exp = attr.value;
var dir = attrName.substring(2);
if (me.isEventDirective(dir)) {
compileUtil.eventHandler(node, me.$vm, exp, dir);
} else {
compileUtil[dir] && compileUtil[dir](node, me.$vm, exp);
}
node.removeAttribute(attrName);
}
});
},
- 对于实现解析指令的核心过程:
bind: function (node, vm, exp, dir) {
var updaterFn = updater[dir + 'Updater'];
updaterFn && updaterFn(node, this._getVMVal(vm, exp));
new Watcher(vm, exp, function (value, oldValue) {
updaterFn && updaterFn(node, value, oldValue);
});
},
- 对于事件处理的核心过程:
eventHandler: function (node, vm, exp, dir) {
var eventType = dir.split(':')[1],
fn = vm.$options.methods && vm.$options.methods[exp];
if (eventType && fn) {
node.addEventListener(eventType, fn.bind(vm), false);
}
},
- 对于值的改变,
get
方法可以进行计算得到属性值,set
方法可以监听属性值的变化,当值发生变化以后更新其它的相关属性值,核心过程代码如下:
_getVMVal: function (vm, exp) {
var val = vm._data;
exp = exp.split('.');
exp.forEach(function (k) {
val = val[k];
});
return val;
},
_setVMVal: function (vm, exp, value) {
var val = vm._data;
exp = exp.split('.');
exp.forEach(function (k, i) {
if (i < exp.length - 1) {
val = val[k];
} else {
val[k] = value;
}
});
}
二、模版解析之事件指令的实现
- 事件指令的实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>模版解析之事件指令_MVVM</title>
</head>
<body>
<div id="test">
<p> {{ name }}</p>
<button v-on:click="test">测试</button>
</div>
</body>
<script type="text/javascript" src="./js/mvvm/compile.js"></script>
<script type="text/javascript" src="js/mvvm/mvvm.js"></script>
<script type="text/javascript" src="./js/mvvm/observer.js"></script>
<script type="text/javascript" src="./js/mvvm/watcher.js"></script>
<script type="text/javascript">
new MVVM({
el: "#test",
data: {
name: "张三"
},
method: {
test() {
alert("事件指令测试");
}
}
})
</script>
</html>
- 关于
vue
的源码分析,我在github
上建立了一个项目,项目地址如下https://github.com/jiuchengTk279/vueSourceCode.git
,欢迎大家访问下载,也希望可以多给予一些建议交流。