之前有简单看过 vue patch 部分的源码,了解了是基于 Snabbdom 库实现的。最近想详细了解下 Vue 处理 vnode patch 的整个过程,想知道它在 Snabbdom 之上做了哪些事情?所以带着这个问题,写了这篇文章来记录。
A virtual DOM library with focus on simplicity, modularity, powerful features and performance. (一个虚拟 DOM 库,专注于简单性,模块化,强大的功能和性能。)
Snabbdom 核心代码大约只有 200 行。它提供了模块化架构,具有丰富的功能,可通过自定义模块进行扩展。在了解核心 patch 前,需要先了解 snabbdom 的模块化架构思想。
在节点的生命周期里做一些任务,来扩展 Snabbdom ,就可以称之为模块。
Snabbdom 在 patch 的过程中会注入很多钩子(hooks)。模块实现就是基于这些钩子,钩子可以理解为 vnode 节点的生命周期。
比如 eventlisteners 模块:
Hooks 是一种挂载 vnode 生命周期的方式。软件开发领域有类似这样的设计思想,比如版本管理工具 git。Snabbdom 中的模块就是基于此来实现扩展的。当然,也可以传递 hook 配置,实现在 vnode 生命周期里做一些事(这种只针对单个节点,而模块针对所有节点),例如:
h('div.row', {
key: movie.rank,
hook: {
insert: vnode => {
movie.elmHeight = vnode.elm.offsetHeight
}
}
})
Vue 中的指令就是基于此实现的。具体的生命周期可以参考官方文档:https://github.com/snabbdom/snabbdom#hooks
Snabbdom 的核心部分,patch 函数由 snabbdom.init 创建,初始化时提供绑定 hook 的模块。
如果 oldVnode 是具有父节点的 DOM 元素,则 newVnode 将变为 DOM 节点,并且传递的元素将被创建的 DOM 节点替换。如果传递的是个 vnode 实例,则会比对此节点和递归对比它的子节点,并做 dom 更新。这一块网上的源码解析文章也比较多,这里就不多介绍了。
h 函数用来创建 vnode 实例,类比 Vue render 函数中的参数 h,Vue 中扩展了入参。比如第一个参数 tag,Vue 可以是对象或函数;第二个参数 data,Vue 增加了一些特有的功能比如:scopedSlots, slot, directive, ref... 等。
Vue 会对静态节点做性能优化。
对于 Vue 服务端渲染输出的 html,客户端初始化挂载节点时,会把已经渲染好的 dom 和 vnode 一一绑定,以达到同构的效果,hydrate 函数就做了这个任务。
我整理了一份比较详细的 patch 流程图。
一些细节没有写入,比如:updateChildren diff 过程、异步组件、keep-alive、hydrate...
Vue 2 中的指令就是基于 hooks 实现的,从 directive 的生命周期来看:
vnode 创建、更新、销毁时都会更新所在组件上的 $refs 属性。
patch 过程中处理了子组件为空时,父组件指向的 ref 为 undefined 的边界情况
对于动态绑定 style,Vue 还会智能的往不支持的属性前加厂商前缀。
const normalize = cached(function(prop) {
emptyStyle = emptyStyle || document.createElement('div').style
prop = camelize(prop)
if (prop !== 'filter' && prop in emptyStyle) {
return prop
}
const capName = prop.charAt(0).toUpperCase() + prop.slice(1)
for (let i = 0; i < vendorNames.length; i++) {
const name = vendorNames[i] + capName
if (name in emptyStyle) {
return name
}
}
})
Vue 还支持 value 数组写法。比如 {display: ["-webkit-box", "-ms-flexbox", "flex"]}
Snabbdom 中对 style 增加了 hooks: remove,这个是为了实现节点被移除时的过渡动效,而 Vue 对过渡动效的处理封装在了 <transition> 组件中。
其实 Vue 中还有很多功能都依赖 vnode 节点 patch 的过程,transition 的功能也比较多,这里暂时不深入了。
由于本人理解有限,文中如有任何问题欢迎留言指正。
来自:http://shuaizhang.top/2019/06/20/Vue基于snabbdom做了哪些事/
VueJS 实际开发中会遇到的问题,主要写一些 官方手册 上没有写,但是实际开发中会遇到的问题,需要一定知识基础。
Vue.js是一套构建用户界面的渐进式的前端框架。 vueJS与后台交互数据的方法我所了解的有以下几种
Vue是一套构建用户界面的JS渐进式框架。 Vue 只关注视图层, 采用自底向上增量开发的设计。讲解js高级之响应式、过渡效果、过渡状态。
深入理解Vue.js响应式原理。Vue教程有关的视频都讲到,我习惯响应式开发,在更早的Angular1时代,我们叫它:数据绑定(Data Binding)。你只需要在Vue实例的 data() 块中定义一些数据,并绑定到HTML
在vue组件中,为了使样式私有化(模块化),不对全局造成污染,可以在style标签上添加scoped属性以表示它的只属于当下的模块,这是一个非常好的举措,但是为什么要慎用呢?因为scoped往往会造成我们在修改公共组件(三方库或者项目定制的组件)的样式困难,需要增加额外的工作量
vue现在使用的人越来越多了,这篇文章主要整理一些比较优秀的移动端ui框架,推荐给大家,例如:mint UI、vux、vonic、vant、cube-ui、Muse-ui、Vue-Carbon、YDUI等
webpack是开发Vue单页应用必不可少的工具,它能管理复杂的构建步骤,并且优化你的应用大小和性能, 使你的开发工作流更加简单。在这篇文章中,我将解释使用webpack提升你的Vue应用的4种方式,包括:单文件组件、优化Vue构建过程、浏览器缓存管理、代码分离
Vue-Access-Control是一套基于Vue/Vue-Router/axios 实现的前端用户权限控制解决方案,通过对路由、视图、请求三个层面的控制,使开发者可以实现任意颗粒度的用户权限控制。
Web 中的组件其实就是页面组成的一部分,具有高内聚性,低耦合度,互冲突等特点,有利于提高开发效率,方便重复使用,简化调试步骤等。vue 中的组件是一个自定义标签形式,扩展原生的html元素,封装可重用的代码。
Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理、数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成、编译、挂着、销毁等过程进行js控制。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!