-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vue早期源码学习系列之八:列表渲染与diff算法 #91
Labels
Comments
new Vue() |
应该是Vmb和Vmc吧。Correct me if I am wrong. |
@LiuMengzhou 是的,此处为笔误,多谢指出,已修正。 |
diff算法那有一点死活想不明白,实例数组[b,c]生成后,为什么要先插入f再插入e,不能先插入e再插入f |
@Geocld 我也疑惑,关于diff算法,这篇文章写得很详细:aooy/blog#2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前言
继上一篇 #90 实现了条件渲染之后,本篇我们来看看如何实现vue列表渲染功能。
问题具象
考虑以下的情况
我们的目标是:根据数组items循环渲染li标签,并且当items改变的时候能够最小化操作DOM完成重新渲染。
思路
我们先来思考一下,总共有几个难点:
父子实例作用域
我们先来解决上面提到的第二个难点:作用域。有没有发现这样一个有趣的现象:父子实例的作用域极度类似于js对象的继承?子实例继承于父实例。比如说,当我们在子实例要找user.name的时候,由于在子实例中找不到user,所以就会沿着原型链跑到父实例上去找,在父实例中找到了user,然后终止查找。当我们在子实例中要找item的时候,因为item是子实例自己的属性,所以在子实例就可以找到,不会跑到父实例上面去找。然而当父实例想访问子实例的item的时候,是无法访问得到的。
综上:通过js的继承,可以解决父子实例的作用域嵌套问题。
具体的实现基本上就是下面这一行代码。
由此导致的另一个相关的问题:
如果我们用继承来实现作用域嵌套,那么,当父实例的user.name改变的时候,如何将变化传导到各个子实例呢?
答案:把子实例存储到父实例的_children数组中,当父实例的data发生变动,触发父实例的updateBindingAt方法的时候,循环遍历_children,分别触发每个子实例的updateBindingAt方法。
那么,具体如何实现呢?
diff算法
第三个难点。vue确保列表渲染性能的核心是:diff算法,整个算法分成两部分:初始化和更新,如下图所示。
初始化
更新
说的比较抽象,更为直接的方式是直接去debug源码,我参考的版本vue版本是这个,自己实现的版本在这里,核心的代码在这里,实现的效果如下图所示。
后话
关于列表渲染的性能优化,本篇实现的只是最简单的版本,我感觉还有很多其他的东西没有实现,有待研究,比如track
参考资料
The text was updated successfully, but these errors were encountered: