导航
display)display: none**v-if 以及 @methods 事件函数
Map)
{ type: 'if/show', prop: data.xxx }methods.xxx 方法methods 事件函数
update 更新页面initData 数据响应式
initPool v-if、v-show、event 放进对应 pool
bindEvent 事件绑定
render 页面渲染
update 页面更新
showPool:

eventPool:

/**
* showPool Map {dom: {}}
* [
* [
* dom,
* {
* type: if/show
* prop: data下边的对应属性
* }
* ]
* ]
*
* eventPool
*
* [
* [
* dom,
* handler
* ]
* ]
*/
var Vue = (function() {
function Vue(options) {
// el
this.$el = document.querySelector(options.el);
this.$data = options.data();
this._init(this, options.template, options.methods);
}
Vue.prototype._init = function(vm, template, methods) {
var container = document.createElement('div');
container.innerHTML = template;
var showPool = new Map();
var eventPool = new Map();
initData(vm, showPool); // 更新的时候要用到showPool
initPool(container, methods, showPool, eventPool);
bindEvent(vm, eventPool);
render(vm, showPool, container);
}
function initData(vm, showPool) {
var _data = vm.$data;
for (var key in _data) {
(function(key) {
Object.defineProperty(vm, key, {
get: function() {
return _data[key];
},
set: function(newVal) {
// this.isShowImg1 = true;
_data[key] = newVal;
update(vm, key, showPool)
}
});
})(key);
}
}
function initPool(container, methods, showPool, eventPool) {
var _allNodes = container.getElementsByTagName('*');
var dom = null;
for (var i = 0; i < _allNodes.length; i++) {
dom = _allNodes[i];
var vIfData = dom.getAttribute('v-if');
var vShowData = dom.getAttribute('v-show');
var vEvent = dom.getAttribute('@click');
if (vIfData) {
showPool.set(
dom,
{
type: 'if',
prop: vIfData
}
)
dom.removeAttribute('v-if');
} else if (vShowData) {
showPool.set(
dom,
{
type: 'show',
prop: vShowData
}
)
dom.removeAttribute('v-show');
}
if (vEvent) {
eventPool.set(
dom,
methods[vEvent]
)
dom.removeAttribute('@click');
}
}
console.log(eventPool);
}
function bindEvent(vm, eventPool) {
for (var [dom, handler] of eventPool) {
vm[handler.name] = handler;
dom.addEventListener('click', vm[handler.name].bind(vm), false);
}
}
function render(vm, showPool, container) {
var _data = vm.$data;
var _el = vm.$el;
for (var [dom, info] of showPool) {
switch (info.type) {
case 'if':
info.comment = document.createComment('v-if');
// 如果为假,就用 comment 节点替换 dom 节点
// replaceChild(newNode, oldNode);
!_data[info.prop] && dom.parentNode.replaceChild(info.comment, dom);
break;
case 'show':
// 如果为假,就设置display为none
!_data[info.prop] && (dom.style.display = 'none');
break;
default:
break;
}
}
_el.appendChild(container);
}
function update(vm, key, showPool) {
var _data = vm.$data;
for (var [dom, info] of showPool) {
if (info.prop === key) {
switch (info.type) {
case 'if':
!_data[key] ? dom.parentNode.replaceChild(info.comment, dom)
: info.comment.parentNode.replaceChild(dom, info.comment);
break;
case 'show':
!_data[key] ? (dom.style.display = 'none')
: (dom.removeAttribute('style'));
break;
default:
break;
}
}
}
}
return Vue;
})();
export default Vue;