虚拟 DOM 的优缺点?

优点:

保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;

无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;

跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。

缺点:

无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

Vue中key的作用

vue 中 key 值的作用可以分为两种情况来考虑:

第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个元素就会被复用。如果是相同的 input 元素,那么切换前后用户的输入不会被清除掉,这样是不符合需求的。因此可以通过使用 key 来唯一的标识一个元素,这个情况下,使用 key 的元素不会被复用。这个时候 key 的作用是用来标识一个独立的元素。

第二种情况是 v-for 中使用 key。用 v-for 更新已渲染过的元素列表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处的每个元素。因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。这个时候 key 的作用是为了高效的更新渲染虚拟 DOM。

key 是为 Vue 中 vnode 的唯一标记,通过这个 key,diff 操作可以更准确、更快速

更准确:因为带 key 就不是就地复用了,在 sameNode 函数a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。

更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

Vue组件data为什么必须是个函数?

根实例对象data可以是对象也可以是函数 (根实例是单例),不会产生数据污染情况

组件实例对象data必须为函数 一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数,

简版理解

// 1.组件的渲染流程 调用Vue.component -> Vue.extend -> 子类 -> new 子类

// Vue.extend 根据用户定义产生一个新的类

function Vue() {

}

function Sub() {

// 会将data存起来

this.data = this.constructor.options.data();

}

Vue.extend = function(options) {

Sub.options = options; // 静态属性

return Sub;

}

let Child = Vue.extend({

data:()=>( {

name: 'zf' })

});

// 两个组件就是两个实例, 希望数据互不感染

let child1 = new Child();

let child2 = new Child();

console.log(child1.data.name);

child1.data.name = 'poetry';

console.log(child2.data.name);

// 根不需要 任何的合并操作 根才有vm属性 所以他可以是函数和对象 但是组件mixin他们都没有vm 所以我就可以判断 当前data是不是个函数

相关源码

// 源码位置 src/core/global-api/extend.js

export function initExtend (Vue: GlobalAPI) {

Vue.extend = function (extendOptions: Object): Function {

extendOptions = extendOptions || {

}

const Super = this

const SuperId = Super.cid

const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {

})

if (cachedCtors[SuperId]) {

return cachedCtors[SuperId]

}

const name = extendOptions.name || Super.options.name

if (process.env.NODE_ENV !== 'production' && name) {

validateComponentName(name)

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: