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: 节点的namespace

    • context: 编译作用域

    • functionalContext: 函数化组件的作用域

    • key: 节点的key属性,用于作为节点的标识,有利于patch的优化

    • componentOptions: 创建组件实例时会用到的选项信息

    • child: 当前节点对应的组件实例

    • parent: 组件的占位节点

    • raw: raw html

    • isStatic: 静态节点的标识

    • 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渲染函数的更多相关文章

  1. vue渲染函数&JSX

    Vue推荐在绝大多数情况下使用template来创建你的HTML.然而在一些场景中,你真的需要JavaScript的完全编程能力,这时你可以使用render函数,它比template跟接近编译器. 虚 ...

  2. Vue渲染函数

    前面的话 Vue 推荐在绝大多数情况下使用 template 来创建HTML.然而在一些场景中,真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更 ...

  3. vue 渲染函数&jsx

    前端更新状态,更新视图,所以性能问题主要由Dom操作引起的,而js解析编译dom渲染就要快得多,  所把要js和html混写. vue 的动态js操作 html  方法:reader函数: vue  ...

  4. Vue 渲染函数

    Vue 推荐在绝大多数情况下使用模板来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力.这时你可以用渲染函数,它比模板更接近编译器. 一 项目结构 二 App组 ...

  5. vue从入门到进阶:渲染函数 & JSX(八)

    Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接 ...

  6. Vue如何用虚拟dom进行渲染view的

    前提 vue版本:v2.5.17-beta.0 触发render vue在数据更新后会自动触发view的render工作,其依赖于数据驱动:在数据驱动的工作下,每一个vue的data属性都被监听,并且 ...

  7. 详解Vue中的虚拟DOM

    摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...

  8. 对vue虚拟dom的研究

    Vue.js通过编译将template 模板转换成渲染函数(render ) ,执行渲染函数就可以得到一个虚拟节点树 在对 Model 进行操作的时候,会触发对应 Dep 中的 Watcher 对象. ...

  9. vue核心之虚拟DOM

    一.前言 虚拟DOM概念随着react的诞生而诞生,由facebook提出,其卓越的性能很快得到广大开发者的认可:继react之后vue2.0也在其核心引入了虚拟DOM的概念,本文将以vue2.0使用 ...

随机推荐

  1. AL32UTF8 and UTF8 and ZHS16GBK

    About AL32UTF8 ORACLE数据库字符集,即Oracle全球化支持(Globalization Support), 或即国家语言支持(NLS)其作用是用本国语言和格式来存储.处理和检索数 ...

  2. HTML学记笔记

    <!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...

  3. [转载非常好的文章]JLink+GDBServer调试S3C6410裸板的初始化代码 For OK6410开发板

    要调试裸板,有两种初始化方法,一个是用烧好的uboot初始化,再有就是直接用JLink+GDBServer初始化.代码参考了网上的资料,根据手头的OK6410开发板做了修改.整体代码如下: # Con ...

  4. 通过浏览器F12开发工具快速获取别的网站前端代码的方法

    通过浏览器F12开发工具快速获取别的网站前端代码的方法 说明:直接另存为网页是比较老的做法,会有很多没用的东西下载下来.通过F12开发工具,sources获取到的是比较好的,有目录结构的源文件.

  5. Load data local infile 实验报告

    1.实验内容: 利用SQL语句“load data local infile”将“pet.txt”文本文件中的数据导入到mysql中 (pet表在数据库menagerie中) 2.实验过程及结果: ( ...

  6. linux 命令中英文对照,收集

    linux 命令中英文对照,收集   linux 命令英文全文 Is Linux CLI case-sensitive? The answer is, yes. If you try to run L ...

  7. 原生JS动态添加和删除类

    原生JS动态添加和删除类 由于需要, 给按钮组监听点击事件(要求用事件委托),当有一个按钮被点击时,相应的给该按钮添加一个类(激活类),其他没有点击的按钮就要移出该类 添加和和删除类有三种方法 首先等 ...

  8. SQL 聚集函数(聚组函数)的使用 注意事项

    原文地址 http://hi.baidu.com/sdunus/blog/item/333c1a29305041fe99250aad.html 在介绍GROUP BY 和 HAVING 子句前,我们必 ...

  9. 前端框架bootstrap(响应式布局)入门

    Bootstrap,是基于HTML,CSS.javascript的前端框架 该框架已经预定义了一套CSS样式和与样式相对应的js代码(对应的样式有对应的特效.) 开发人员只需要编写HTML结构,添加b ...

  10. 5、Storm集成Kafka

    1.pom文件依赖 <!--storm相关jar --> <dependency> <groupId>org.apache.storm</groupId> ...