主要思路通过改造data数据的set方法,当数据发生变时(v-mode,v-click)通知watcher去执行update
- js代码
function zlVue(options){
this.init(options)
}
//初始化构造函数
zlVue.prototype.init = function(options){
this.$el = document.querySelector(options.el);
this.$data = options.data;
this.$methods = options.methods;
this._bind = {}
this._initDate(this.$data);
this._initEl(this.$el)
}
//重写data的set和get函数
zlVue.prototype._initDate = function(obj){
for(key in obj){
this._bind[key] = {
_funArr:[]
}
var value = obj[key]
if(typeof value ==='object'){
this._initDate(value)
}
}
var _this = this
//set方法中,只要值发生改变就执行update()去更新视图
Object.defineProperty(this.$data,key,{
enumerable:true,
configurable:true,
get: function(){
return value
},
set: function(newValue){
if(newValue !== value){
value = newValue;
_this._bind[key]._funArr.forEach(function(v){
v.update()
})
}
}
})
}
//对页面进行初始化
zlVue.prototype._initEl = function(el){
var _this = this
var nodes = el.children;
for(var i = 0;i < nodes.length; i++){
var node = nodes[i]
if(node.length){
this._initEl(node);
}
//对绑定的data,进行状态
if(node.hasAttribute('v-click')){
node.onclick = (function(){
var funName = node.getAttribute('v-click');
return _this.$methods[funName].bind(_this.$data)
})();
}
if(node.hasAttribute('v-bind')){
var dataName = node.getAttribute('v-bind');
_this._bind[dataName]._funArr.push(new Watcher(node,_this,dataName,'innerHTML'))
}
if(node.hasAttribute('v-model') && (node.tagName === 'INPUT' || nodoe.tagName === 'TEXTAREA')){
node.addEventListener('input',(function(key) {
var dataName = node.getAttribute('v-model');
_this._bind[dataName]._funArr.push(new Watcher(
node,
_this,
dataName,
'value'
))
return function() {
_this.$data[dataName] = nodes[key].value;
}
})(i))
}
}
}
//数据变化是实现对DOM元素的更新:
function Watcher(el,vm,exp,attr){
this.el =el,
this.vm = vm,
this.exp = exp,
this.attr = attr,
this.update()
}
Watcher.prototype.update = function(){
this.el[this.attr] = this.vm.$data[this.exp];
}
- 实例化
window.onload = function(){
var app = new zlVue({
el:'#app',
data: {
number: 0
},
methods: {
inerement: function(){
this.number ++;
},
}
})
}
- html代码
<div id="app">
<form>
<input type="text" v-model="number">
<button type="button" v-click="inerement">add</button>
</form>
<h3 v-bind="number"></h3>
</div>
-
实际效果图
image.png
image.png
网友评论