diff算法
1.普通的应用在git 上,git diff 命令就是找出两个文本文件的差异,linux的基础命令
2.vdom 使用diff算法原因:
找出dom必须更新的节点来更新
3.diff实现过程
patch(container,vnode)//初始化节点
patch(vnode,newVnode)//找出差异,更新节点到 与原来的vnode节点上
function createElement(vnode){
var tag=vnode.tag;
var attrs=vnode.attrs || {};
var children=vnode.children || [];
if(!tag ){
return null;
}
//创建真实的dom元素
var ele=document.createElement(tag);
//属性
var attrName
//遍历属性
for(attrName in attrs){
if(attrs.hasOwnProperty(attrName)){
//给ele添加属性
ele.setAttribute(attrName,attrs[attrName])
}
}
//子元素
children.forEach(function(childVnode){
//给ele添加真实的子元素(递归)
ele.appendChild(createElement(childVnode))
})
//返回真实的dom 元素
return ele
}
function updateChildren(vnode,newVnode){
var children=vnode.children || [];
var newChildren=newVnode.children || [];
children.forEach(function(childVnode,index){
var newChildVnode=newChildren[index];
//判断标签是否有变更
if(childVnode.tag === newChildVnode.tag){
//没有变更再深层次对比,递归方式
updateChildren(childVnode,newChildVnode)
}else{
//标签有变化则执行替换
replaceNode(childVnode,newChildVnode)
}
})
}
function replaceNode(vnode,newVnode){
var ele=vnode.ele;//真实的dom节点
var newEle=createElement(newVnode)
}
总结:
1.初次渲染创建真实dom元素
2.遍历属性,给元素添加属性名
3.子节点循环输出(递归的形式遍历出元素节点)
4.返回真实的dom元素
5.重新渲染的节点进入
6.新节点与原来真实的dom元素对比(无变化继续递归循环自身直到找到有差异)
7.对于有差异的节点执行replaceNode(node,newNode)
将新节点替换掉初次渲染节点
8.返回真实的节点去创建真实的dom节点再次去渲染页面