vue中key的作用

您所在的位置:网站首页 核爆末日余生317地堡任务 vue中key的作用

vue中key的作用

#vue中key的作用| 来源: 网络整理| 查看: 265

本文将从以下几点带你深入了解vue中的key在何处起作用,作用又是什么:

vue的生命周期 beforeUpdate生命周期详解 diff算法 key在diff中的作用 vue的生命周期

大家都知道vue属于MVVM架构,他的生命周期总体可以分为创建期,运行期和销毁期。对应的生命周期钩子为:

beforeCreate:在这个阶段只是创建了一个vue的vm实例,但并未进行数据的初始化,也就是说这个时候的vue实例只是个空壳,内部什么都没有,因此在这个阶段是不能访问到在模板文件中定义的属性。 created:在这个阶段,对定义的props,methods,data,computed,watch等进行初始化,因此想要获取模板中定义的data属性,最早也只能在这个阶段获取。 beforeMount: 将模板文件编翻译成一个渲染函数,但是并未进行挂载。 mounted:将上一步的渲染函数挂载到真实节点el中去。这里也就说明了为什么最早获取dom节点需要在mounted阶段,在mounted之前的都是准备工作,真正挂载到真是节点是mounted阶段 beforeUpdate: 补丁已经生成,但并未渲染。 updated: 补丁包已经被重新渲染到界面中去。本次更新完毕。 beforeDestroy: vue实例销毁之前,在此阶段可以进行一些清除倒计时或者取消监听的操作 destroyed:组件已经销毁 beforeUpdate生命周期详解

vue通过Object.defineProperty()监听数据的改变,在getter中进行依赖收集,setter中派发事件。当数据的值发生改变时,会触发对应的watcher,在vue内部维持了一个异步任务队列,用来存放这些watcher,需要注意的就是相同的watcher只会被推入一次,异步的好处是可以一次性将新旧虚拟DOM进行比较,生成一个补丁,之后再一次性的渲染到实际的DOM中去,这样既较少了DOM的操作,又能有效的减少页面的回流与重绘。beforeUpdate期间就是将异步任务队列里的watcher执行,生成一个全新的虚拟DOM节点,之后进行新旧虚拟DOM的比较,生成一个补丁包,这个补丁包会在updated阶段被渲染到真实的DOM中去,可以看出,在beforeUpdate阶段,最重要的事情就是新旧虚拟DOM的比较以及生成补丁包,如何进行新旧虚拟DOM的比较呢?这就要用到下文所说的diff算法了

diff算法

首先需要明白的是,不止vue有diff算法,只要涉及到虚拟DOM的,都会有diff算法。diff算法他的作用就是进行两个虚拟DOM的比较,最后生成一个补丁包。他的比较遵循以下几点:

深度优先遍历,也就是当两个节点进行比较时,如果有子节点,那么会先进行子节点的比较。树的中序遍历迭代算法就是深度优先的遍历。 只会进行同层之间的比较,如果进行同层与非同层的比较的话,时间复杂度会大大增加,举个简单的例子就是,同层比较就相当于你只有一个for循环,当进行同层与非同层之间的比较的话,那么相当于是for中嵌套for,当嵌套太深,那么时间复杂度可想而知 // 同层比较 for(var i = 0; i < tag; i++) { // 时间复杂度为O(n) } // 同层与非同层 for(var i = 0; i < parent; i++) { //时间复杂度为O(n(嵌套)) for(var j = 0; j < child1; j++) { for(...) { ... } } } 在进行新旧虚拟DOM比较时,会进行四次比较,分别是 新的虚拟DOM头与旧的虚拟DOM头 新的虚拟DOM头与旧的虚拟DOM尾 新的虚拟DOM尾与旧的虚拟DOM尾 旧的虚拟DOM头与新的虚拟DOM尾 如果以上都找不到的话,就会进行遍历查找 最后生成补丁包 key在diff中的作用

可以看出在在diff中,如果四次比较都未能命该节点的话,最后只能进行遍历查找,遍历查找的时间复杂度为O(n),但是如果给节点加上唯一的key值的话,在查找不到的时候,只需要通过key去获取是否有匹配的,如果没有,则说明是新增加或者删除的。需要明确的是,虚拟DOM看的明白点也就是一个对象,而对象又是一个散列表,散列表通过key获取value的时间复杂度为O(1),因此能大大的提高效率。因此这也是为什么建议需要写入唯一key值的原因。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3