vue

197 阅读4分钟

v-if和v-for的优先级

  • 源码的编译过程,对于v-for的判断是在v-if之前的
  • 最后生成的render函数,也是以_l做循环,v-if最终被转换为3目

结论:

  1. v-for的优先级大于v-if
  2. 同时出现时,也是先执行循环,再加判断语句
  3. 个人建议直接渲染过滤后的列表好了

vue组件的data为什么是函数

  • 源码中mergeOptions对data的合并处理,对根实例的data和组件的data是有区别的。根实例会多传一个参数做标识,没有这个标识,会做判断,必须是function。
  • 自定义组件是先去调用component方法,该方法生成构造函数,期间会合并选项
  • 合并选项时,只有传递了第三个参数,才能是对象(待定)
  1. vue组件实例会有多个,所以data不能是对象
  2. vue根实例只有一个,不存在这个问题

key的作用和原理

[a,b,c,d,e]
[a,b,f,c,d,e]
在数组的c前边加入 f

没有key时

  • 循环遍历,先对key和tag做比较,发现都是相同节点
  • a,b不做任何操作
  • c,d,e都会做contentText的更新
  • 旧的节点遍历完了,发现新的比旧的节点多,直接创建并插入f

有key时

  • a,b都是头头索引一样。不做更新
  • 此时旧的头索引c和f、e的key都不同,再拿旧尾索引和新的头尾比较,找到新的尾索引
  • 尾索引与尾索引比较完,各自减减。比较d和d、c和c。同理都是尾索引减减
  • 旧的节点循环走完,发现新的节点多,就把f插入到此时旧索引对应的c前边

没有key时,3次更新、1次插入

有key时,只有1次插入

结论:

  1. key的作用是高效地更新vdom,原理就是在patch过程,判断是否是同一节点,避免频繁更新不同元素,最小的更新dom,使得patch过程更高效,提高性能
  2. 不加key有时候可能会导致列表bug (待定)
  3. 相同标签相同元素过渡时,加key可以使得vue更好的区分,否则vue只会替换其内部属性,而不触发过渡效果(待定)

怎么看diff

结论: 凡是用到vdom,必然要使用diff算法,降低复杂度为O(n) 比较的策略:深度优先、同层比较 必要性:vue2降低了watcher的粒度,每个组件只有一个watcher,只有引入diff才能精确找到需要更新的节点 修改了数据,由于数据响应式劫持,触发了set里dep的通知函数,将watcher添加到异步更新队列中。watcher的更新函数,调用了组件的渲染函数和更新函数。这个过程就是patch

组件化

两种定义方式:全局定义、单文件组件形式

特点:把程序中独立的功能和模块单独抽离出来,有独立的逻辑、更好的复用性

全局组件: 继承于vue的原型的拷贝,VueComponent继承于Vue,然后又注册到全局。

单文件组件:

Vue.component("comp", {
  template: `<div>comp</div>`
})

  • 执行vue.component时,首先是创建comp的构造函数,并将构造函数挂到本身的options中
  • 最后又将组件的构造函数挂载到Vue的构造函数的components中,所以全局都可以使用到
  • 在执行patch方法,createElem时,createComponent检测是否有init钩子,有则创建组件实例
  • 其实写的是组件配置文件,最终webpack会调用vue-loader,将所有template编译为render,最终导出的是js对象,就是组件的配置对象,而不是构造函数

vue设计理念

渐进式js框架、易用、灵活、高效

渐进式: 只想学习核心部门,就只需要学习下模板语法、组件系统,就可以开发了 当规模变大,需要引入其他的工具链的时候,可以再学习额外知识 不管是架构、学习,都是易用性

易用: 数据驱动的理念,只需要有基础的js、html、css就可以了 声明式地将数据渲染到dom系统

灵活:渐进式本身就是灵活,项目小,完全可以只使用核心功能

高效:vdom和diff

vue为什么要求组件模板只有一个根元素

总结两点:

  • new vue(el: “”) 源码中获取el,用的是document.querySelector,假如两个class元素,只会返回第一个
  • template只能有一个div