从虚拟dom了解vue渲染函数
vue渲染函数就是render函数,他会返回一个VNode,VNode是一个js对象,是dom的映射
vue在介绍渲染函数那个章节看的不是很懂,所以想要彻底的理解渲染函数,首先需要了解vue的虚拟dom
关于虚拟dom的介绍,这里有一篇很好的文章,我也是看了这篇才茅塞顿开:https://www.zhihu.com/question/29504639
我来概括一下虚拟dom的工作是将浏览器的dom节点的所有信息映射到一个js对象上面,因为js本身是很快的,但是dom操作本身很慢,如果我们把dom的信息映射到js对象上面,至少当获取dom信息时候 我们不需要去遍历dom了,而另一方面对于dom的操作一直是js优化的重点,使用虚拟dom,程序员不需要自己去操作dom,所以关于dom的操作都会由虚拟dom完成,而虚拟dom一定会以最优方案来进行操作,所以虚拟dom的重点是构建一个浏览器dom的信息拷贝树,拷贝树里面必须包含所有dom节点的拷贝节点,我们把这个拷贝节点叫做VNode
关于虚拟dom的好处还有一个就是vue会把所有的dom操作缓存到一个队列,这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。请看vue官方对于异步更新队列的解释:https://cn.vuejs.org/v2/guide/reactivity.html,
刚才我们说到VNode是什么,那VNode里面包含哪些信息呢:
tag
: 当前节点的标签名data
: 当前节点的数据对象,具体包含哪些字段可以参考vue源码types/vnode.d.ts
中对VNodeData
的定义children
: 数组类型,包含了当前节点的子节点text
: 当前节点的文本,一般文本节点或注释节点会有该属性elm
: 当前虚拟节点对应的真实的dom节点ns
: 节点的namespacecontext
: 编译作用域functionalContext
: 函数化组件的作用域key
: 节点的key属性,用于作为节点的标识,有利于patch的优化componentOptions
: 创建组件实例时会用到的选项信息child
: 当前节点对应的组件实例parent
: 组件的占位节点raw
: raw htmlisStatic
: 静态节点的标识isRootInsert
: 是否作为根节点插入,被<transition>
包裹的节点,该属性的值为false
isComment
: 当前节点是否是注释节点isCloned
: 当前节点是否为克隆节点isOnce
: 当前节点是否有v-once
指令
那如何创建VNode呢,首先为什么要创建VNode,因为我们使用vue所有的操作都是针对vue的虚拟dom也就是VNode的,然后vue将虚拟dom更新到真实dom,而我们经常使用的vue组建 也是在底层先变成虚拟dom然后再变成真实dom,拿好了 既然组建是先变成虚拟dom再变成VNode,那我们理论上可以自己创建VNode,然后让vue将我们创建的VNode更新到真实dom上,这样更自由 权限更大,创建VNode的方法是createElement
createElement(tag,{},[]) 或者createElement(tag,{},string)
其中tag是创建元素的标签名
{}是创建元素的属性
[]是创建元素的子元素列表
string是文本
所以最终我们可以这样使用createElement:
Vue.component('anchored-heading', { render: function (createElement) { return createElement( 'h' + this.level, // tag name 标签名称 this.$slots.default // 子组件中的阵列 ) }, props: { level: { type: Number, required: true } } })
关于this.$slots.defalt:
slot我们知道是插槽,关于插槽我认为最好的解释是:在父组件中放入已被 `slot` 标记的内容,这些内容的顺序可以随意。之后这些内容被分发到子组件的特殊元素 `slot` 中,根据 `name` 属性在子组件中重新组合。this.$slots用来访问被插槽分发的内容,这一点vue解释的很清楚:https://cn.vuejs.org/v2/api/#vm-slots
这里使用一个例子来加深this.$slots.defalt的理解:
var getChildrenTextContent = function (children) { return children.map(function (node) { return node.children ? getChildrenTextContent(node.children) : node.text }).join('') } Vue.component('anchored-heading', { render: function (createElement) { // create kebabCase id var headingId = getChildrenTextContent(this.$slots.default) .toLowerCase() .replace(/\W+/g, '-') .replace(/(^\-|\-$)/g, '') return createElement( 'h' + this.level, [ createElement('a', { attrs: { name: headingId, href: '#' + headingId } }, this.$slots.default) ] ) }, props: { level: { type: Number, required: true } } })
这里我们首先getChildrenTextContent,getChildrenTextContent方法的参数是一个数组,说明this.$slot.defaul是一个数组,他其实就是[VNode,Vnode..],this.$slot.default数组里每一个都是VNode对象,上文我们提到到VNode有哪些属性,所以我们看到getChildrenTextContent方法里去判断VNode的children属性,如果VNode有子元素就继续向下寻找,如果没有则直接取他的文本,所以最终我们拿到的是准备放在slot位置的所有非具名元素的文本的拼接。
从虚拟dom了解vue渲染函数的更多相关文章
- vue渲染函数&JSX
Vue推荐在绝大多数情况下使用template来创建你的HTML.然而在一些场景中,你真的需要JavaScript的完全编程能力,这时你可以使用render函数,它比template跟接近编译器. 虚 ...
- Vue渲染函数
前面的话 Vue 推荐在绝大多数情况下使用 template 来创建HTML.然而在一些场景中,真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更 ...
- vue 渲染函数&jsx
前端更新状态,更新视图,所以性能问题主要由Dom操作引起的,而js解析编译dom渲染就要快得多, 所把要js和html混写. vue 的动态js操作 html 方法:reader函数: vue ...
- Vue 渲染函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力.这时你可以用渲染函数,它比模板更接近编译器. 一 项目结构 二 App组 ...
- vue从入门到进阶:渲染函数 & JSX(八)
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接 ...
- Vue如何用虚拟dom进行渲染view的
前提 vue版本:v2.5.17-beta.0 触发render vue在数据更新后会自动触发view的render工作,其依赖于数据驱动:在数据驱动的工作下,每一个vue的data属性都被监听,并且 ...
- 详解Vue中的虚拟DOM
摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...
- 对vue虚拟dom的研究
Vue.js通过编译将template 模板转换成渲染函数(render ) ,执行渲染函数就可以得到一个虚拟节点树 在对 Model 进行操作的时候,会触发对应 Dep 中的 Watcher 对象. ...
- vue核心之虚拟DOM
一.前言 虚拟DOM概念随着react的诞生而诞生,由facebook提出,其卓越的性能很快得到广大开发者的认可:继react之后vue2.0也在其核心引入了虚拟DOM的概念,本文将以vue2.0使用 ...
随机推荐
- Qt QLabel 大小随内容自动变化 && 内容填充整个label空间
图1:label的本身大小 图2:给label设置文字,不做任何别的设置 ui->label->setText(QObject::tr("current font is %1&q ...
- 北京大学Cousera学习笔记--2-计算导论与C语言基础-第一讲.计算机的基本原理-图灵机
有限状态读写头从一个初始状态开始,对存储器上的输入数据进行读或写操作,经过有限步操作之后停机,此时存储器上的输出数据就是计算结果 (1) 图灵机的构成: 1.一条存储带:双向无限延长:上有一个个的小方 ...
- Object:所有类的超类
Java中每个类都是由Object类扩展而来 1.equals方法 在Object类中,这个方法用于判断两个对象是否具有相同的引用,然而对于大多数类来说,经常需要检测两个对象状态的相等性. publi ...
- zuul 自定义路由规则
1,zuul的maven配置 <!--spring cloud 相关包--><parent> <groupId>org.springframework.boot&l ...
- 使用python连接mysql/oracle
最近python比较火,我本身觉得python这种语言速度也不快,做项目也一般,学他干啥?但是了解到python把其他语言的函数封装成了自己的包,用python就可以直接调用,感觉python还是值得 ...
- redis命令行操作
打开shell,首先开启redis服务,在保证服务开启的情况下,打开客户端. 然后可以根据文档,进行命令行试验.
- 组件 restful_API
1 token 认证 2 权限 3 注册器和响应 4 频率组件
- CCF CSP 201412-1 门禁系统
题目链接:http://118.190.20.162/view.page?gpid=T21 问题描述 试题编号: 201412-1 试题名称: 门禁系统 时间限制: 1.0s 内存限制: 256.0M ...
- js开发环境配置
使用Sublime Text3作为主要开发工具.下载地址:http://www.sublimetext.com/3. sublime拥有大量实用插件,使用插件需要先下载PackageControl以便 ...
- html5中视频播放问题总结
html5中视频播放问题总结 文章 1.问题一 框架? 加个标签就OK! <video id="video1" src="/video1.mp4" con ...