资讯专栏INFORMATION COLUMN

Vue 进阶系列(三)之Render函数原理及实现

geekidentity / 2103人阅读

摘要:进阶系列一之响应式原理及实现进阶系列二之插件原理及实现进阶系列三之函数原理及实现函数原理根据第一篇文章介绍的响应式原理,如下图所示。在初始化阶段,本质上发生在函数中,然后通过函数生成,根据生成。负责收集依赖,清除依赖和通知依赖。

(关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导)

Vue进阶系列汇总如下,欢迎阅读,欢迎加高级前端进阶群一起学习(文末)。

Vue 进阶系列(一)之响应式原理及实现

Vue 进阶系列(二)之插件原理及实现

Vue 进阶系列(三)之Render函数原理及实现

Render函数原理

根据第一篇文章介绍的响应式原理,如下图所示。

在初始化阶段,本质上发生在auto run函数中,然后通过render函数生成Virtual DOMview根据Virtual DOM生成Actual DOM。因为render函数依赖于页面上所有的数据data,并且这些数据是响应式的,所有的数据作为组件render函数的依赖。一旦这些数据有所改变,那么render函数会被重新调用。

在更新阶段,render函数会重新调用并且返回一个新的Virtual Dom,新旧Virtual DOM之间会进行比较,把diff之后的最小改动应用到Actual DOM中。

Watcher负责收集依赖,清除依赖和通知依赖。在大型复杂的组件树结构下,由于采用了精确的依赖追踪系统,所以会避免组件的过度渲染。

Actual DOM 和 Virtual DOM

Actual DOM 通过document.createElement("div")生成一个DOM节点。

document.createElement("div")

// 浏览器原生对象(开销大)
"[object HTMLDivElement]"

Virtual DOM 通过 vm.$createElement("div")生成一个JS对象,VDOM对象有一个表示div的tag属性,有一个包含了所有可能特性的data属性,可能还有一个包含更多虚拟节点的children列表。

vm.$createElement("div")

// 纯JS对象(轻量)
{ tag: "div", data: { attrs: {}, ...}, children: [] }

因为Virtual DOM的渲染逻辑和Actual DOM解耦了,所以有能力运行在的非浏览器环境中,这就是为什么Virtual DOM出现之后混合开发开始流行的原因,React Native 和 Weex能够实现的原理就是这个。

JSX和Template

JSX和Template都是用于声明DOM和state之间关系的一种方式,在Vue中,Template是默认推荐的方式,但是也可以使用JSX来做更灵活的事。

JSX更加动态化,对于使用编程语言是很有帮助的,可以做任何事,但是动态化使得编译优化更加复杂和困难。

Template更加静态化并且对于表达式有更多约束,但是可以快速复用已经存在的模板,模板约束意味着可以在编译时做更多的性能优化,相对于JSX在编译时间上有着更多优势。

实例1:实现example组件

要求使用如下

要求输出如下

0

1

2

上面这个需求可以通过render函数来做,官方提供了createElement 函数用来生成模板。createElement("div", {}, [...])可接受的参数如下。

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // 一个 HTML 标签字符串,组件选项对象,或者
  // 解析上述任何一种的一个 async 异步函数。必需参数。
  "div",

  // {Object}
  // 一个包含模板相关属性的数据对象
  // 你可以在 template 中使用这些特性。可选参数。
  {
    
  },

  // {String | Array}
  // 子虚拟节点 (VNodes),由 `createElement()` 构建而成,
  // 也可以使用字符串来生成“文本虚拟节点”。可选参数。
  [
    "先写一些文字",
    createElement("h1", "一则头条"),
    createElement(MyComponent, {
      props: {
        someProp: "foobar"
      }
    })
  ]
)

知道了用法之后,就可以在render中返回createElement生成的虚拟节点,外层是div,内层是三个锚点标题h1 h2 h3,所以内层需要遍历下,使用两个createElement就可以完成了。

通常使用h作为createElement的别名,这是Vue的通用惯例,也是JSX的要求。

实现如下





实例2:实现动态的组件

要求如下

实现一个Foo组件渲染

foo
,实现一个Bar组件渲染
bar

实现一个组件,根据属性ok动态渲染Foo组件或者Bar组件。如果属性oktrue,那么最终的渲染应该是

foo

实现一个按钮控制属性ok,通过这个属性让Foo或者Bar之间切换。

根据上面的要求,在模板中调用组件,然后定义

实例3:实现组件

要求如下

实现一个withAvatarURL函数,要求传入一个带有url属性的组件,返回一个接收username属性的高阶组件,这个高阶组件主要负责获取相应的头像URL。

在API返回之前,高阶组件将占位符URLhttp://via.placeholder.com/200x200传递给内部组件。

例子如下

const SmartAvatar = withAvatarURL(Avatar)

// 使用这个方式


// 替换下面的方式

withAvatarURL函数返回一个对象,接收username属性,在生命周期created获取头像URL。Avatar对象接收src属性,src的内容从withAvatarURL中获取,然后展示在上。实例化的时候,传入新定义的组件名SmartAvatar

实现如下





本文内容参考自VUE作者尤大的付费视频         
Vue官网之渲染函数 & JSX
交流

本人Github链接如下,欢迎各位Star

http://github.com/yygmind/blog

我是木易杨,网易高级前端工程师,跟着我每周重点攻克一个前端面试重难点。接下来让我带你走进高级前端的世界,在进阶的路上,共勉!

如果你想加群讨论每期面试知识点,公众号回复[加群]即可

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99093.html

相关文章

  • Vue 进阶系列(一)响应式原理实现

    摘要:进阶系列一之响应式原理及实现进阶系列二之插件原理及实现进阶系列三之函数原理及实现什么是响应式表示一个状态改变之后,如何动态改变整个系统,在实际项目应用场景中即数据如何动态改变。描述符必须是这两种形式之一,但二者不能共存,不然会出现异常。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导)showImg(https://githu...

    MonoLog 评论0 收藏0
  • Vue 进阶系列(二)插件原理实现

    摘要:示例输出第一步先不考虑插件,在已有的中是没有这个公共方法的,如果要简单实现的话可以通过钩子函数来,即在里面验证逻辑。按照插件的开发流程,应该有一个公开方法,在里面使用全局的方法添加一些组件选项,方法包含一个钩子函数,在钩子函数中验证。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导)showImg(https://segmen...

    wuaiqiu 评论0 收藏0
  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    sutaking 评论0 收藏0
  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    khs1994 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<