从虚拟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>包裹的节点,该属性的值为falseisComment: 当前节点是否是注释节点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使用 ...
随机推荐
- django请求接收及文件上传
在写后端交互页面的时候常常会遇到接收来自前端页面请求的情况,例如 在写注册页面的时候,会提交一些页面信息,这时需要分三种情况讨论 第一种,接收单项信息: v = request.POST.getlis ...
- Mysql AVG() 值 返回NULL而非空结果集
[1]select 查询返回一行NULL 先来模拟复现一下遇到的问题. (1)源数据表grades,学生成绩表 (2)查询SQL语句 查询‘080601’班的各门课平均成绩 SELECT sClass ...
- flask实战-个人博客-虚拟环境、项目结构
个人博客 博客是典型的CMS(Content Management system,内容管理系统),通常由两部分组成:一部分是博客前台,用来展示开放给所有用户的博客内容:另一部分是博客后台,这部分内容仅 ...
- Flask实战-留言板-使用Faker生成虚拟数据
使用Faker生成虚拟数据 创建虚拟数据是编写Web程序时的常见需求.在简单的场景下,我们可以手动创建一些虚拟数据,但更方便的选择是使用第三方库实现.流行的python虚拟数据生成工具有Mimesis ...
- Java第一次实训课
//1.1 声明一个整型变量a,并赋初值5,在程序中判断a是奇数还是偶数,然后输出判断的结果. package mingye; public class Exc { public static voi ...
- CCF CSP 201709-1 打酱油 (贪心)
题目链接:http://118.190.20.162/view.page?gpid=T63 问题描述 试题编号: 201709-1 试题名称: 打酱油 时间限制: 1.0s 内存限制: 256.0MB ...
- etcd v3 备份恢复
备份数据: # ETCDCTL_API=3 etcdctl --endpoints localhost:2379 snapshot save snapshot.db 恢复数据: # ETCDCTL_A ...
- java线程学习之join方法
join()方法表示一个线程要加入另一个线程,直到被加入的线程执行完毕. 这个概念不好理解的话看面这个例子 public class TestJoin { public static void mai ...
- [Python数据挖掘]第5章、挖掘建模(上)
一.分类和回归 回归分析研究的范围大致如下: 1.逻辑回归 #逻辑回归 自动建模 import pandas as pd from sklearn.linear_model import Logist ...
- raphael参数说明
大纲 :first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-pr ...