思维导图
0. 从常见问题引入
- 虚拟dom是什么?
- 如何创建虚拟dom?
- 虚拟dom如何渲染成真是dom?
- 虚拟dom如何patch(patch)
- 虚拟DOM的优势?(性能)
- Vue中的key到底有什么用,为什么不能用index?
- Vue中的diff算法实现
- diff算法是深度还是广度优先遍历
1. 生成虚拟dom
1. h方法实现
virtual dom ,也就是虚拟节点
- 它通过js的Object对象模拟dom中的节点
- 再通过特定的render方法将其渲染成真实的dom节点
eg:
<div id="wrapper" class="1">
<span style="color:red">hello</span>
world
</div>
如果利用h方法生成虚拟dom的话:
h('div', {
id: 'wrapper', class: '1' }, h('span', {
style: {
color: 'red' } }, 'hello'), 'world');
对应的js对象如下:
let vd = {
type: 'div',
props: {
id: 'wrapper', class: '1' },
children: [
{
type: 'span',
props: {
color: 'red' },
children: [{
}]
},
{
type: '',
props: '',
text: 'world'
}
]
}
自己实现一个h方法
function createElement(type, props = {
}, ...children) {
// 防止没有传值的话就赋值一个初始值
let key;
if (props.key) {
key = props.key
delete props.key
}
// 如果孩子节点有字符串类型的,也需要转化为虚拟节点
children = children.map(child => {
if (typeof child === 'string') {
// 把不是节点类型的子节点包装为虚拟节点
return vNode(undefined, undefined, undefined, undefined, child)
} else {
return child
}
})
return vNode(type, props, key, children)
}
function vNode(type, props, key, children, text = undefined) {
return {
type,
props,
key,
children,
text
}
}
2. render方法实现
render的作用:把虚拟dom转化为真实dom渲染到container容器中去
export function render(vnode, container) {
let ele = createDomElementFrom(vnode) //通过这个方法转换真实节点
if (ele) container.appendChi