v-if和v-for的优先级
- 源码的编译过程,对于v-for的判断是在v-if之前的
- 最后生成的render函数,也是以_l做循环,v-if最终被转换为3目
结论:
- v-for的优先级大于v-if
- 同时出现时,也是先执行循环,再加判断语句
- 个人建议直接渲染过滤后的列表好了
vue组件的data为什么是函数
- 源码中mergeOptions对data的合并处理,对根实例的data和组件的data是有区别的。根实例会多传一个参数做标识,没有这个标识,会做判断,必须是function。
- 自定义组件是先去调用component方法,该方法生成构造函数,期间会合并选项
- 合并选项时,只有传递了第三个参数,才能是对象(待定)
- vue组件实例会有多个,所以data不能是对象
- 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次插入
结论:
- key的作用是高效地更新vdom,原理就是在patch过程,判断是否是同一节点,避免频繁更新不同元素,最小的更新dom,使得patch过程更高效,提高性能
- 不加key有时候可能会导致列表bug (待定)
- 相同标签相同元素过渡时,加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