1.7 Vue 渲染函数及JSX语法

1. 渲染函数

渲染函数(render函数)
  • 通过 createElement 函数来创建虚拟DoM(VirtualDom),这个虚拟DOM包含的信息会告诉Vue页面上需要渲染出什么元素。
  • 可以解决有些场景中用 template 实现起来代码冗长繁琐,而且有大量重复的问题。
渲染函数解析
  • render函数的返回值 VNode (即:虛拟节点),也就是我们要渲染的节点。
  • render函数的参数 createElement 是 render 函数的参数,它本身也是个函数,并且有三个参数。 createElement 函数的返回值也是 VNode虚拟节点。
    demo
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
      </head>
      <body>
          <div id="app"></div>
      </body>
      <script>
          Vue.component('heading-line', {
              render: function(createElement) {
                  return createElement(
                      'h' + this.level,// 第一个参数是必选参数,可以是一个HTML标签,也可以是一个组件或函数。这里是标签名称
                      // 第二个参数是可选参数,数据对象,在template中使用,这里省略
                      this.$slots.default// 第三个是子节点,也是可选参数,需要渲染的子节点数组,它会将slot里面的内容分发到相应的节点上去
                  )
              },
              props: {
                  level: {// 做校验,因为不做验证可能出一些bug
                      type: Number,
                      required: true
                  }
              }
          })
      
          new Vue({
              el: '#app',
              template: "<div><heading-line :level='1'>我是标题</heading-line></div>"
          })
      </script>
      </html>
    

2.认识节点、树及虚拟DOM

概念
  • 当浏览器读到一些DOM结构时,会建立一个“DOM节点”树来保持追踪所有内容,如同你会画一张家谱树来追踪家庭成员的发展一样。
  • 虚拟DOM(VirtualDom)就是通过一种 VNode(节点)类表达的,每个DOM元素或组件都对应一个 VNode对象。
  • 使用 javascript对象模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息。
VNode对象源码

每个DOM元素或组件都对应一个VNode对象,具体含义见代码所示
路径:src/core/vdom/vnode.js

    this.tag = tag // 当前节点标签名
    this.data = data // 当前节点数据(VNodeData类型)
    this.children = children // 当前节点子节点
    this.text = text // 当前节点文本
    this.elm = elm // 当前节点对应的真实DOM节点
    this.ns = undefined // 当前节点命名空间
    this.context = context // 当前节点上下文
    this.fnContext = undefined // 函数化组件上下文
    this.fnOptions = undefined // 函数化组件配置项
    this.fnScopeId = undefined // 函数化组件ScopeId
    this.key = data && data.key // 子节点key属性
    this.componentOptions = componentOptions // 组件配置项 
    this.componentInstance = undefined // 组件实例
    this.parent = undefined // 当前节点父节点
    this.raw = false // 是否为原生HTML或只是普通文本
    this.isStatic = false // 静态节点标志 keep-alive
    this.isRootInsert = true // 是否作为根节点插入
    this.isComment = false // 是否为注释节点
    this.isCloned = false // 是否为克隆节点
    this.isOnce = false // 是否为v-once节点
    this.asyncFactory = asyncFactory // 异步工厂方法 
    this.asyncMeta = undefined // 异步Meta
    this.isAsyncPlaceholder = false // 是否为异步占位
节点、树及虚拟DOM

虚拟DOM不是真正意义上的DOM,而是一个轻量级的js对象,在状态改变的时候,虚拟DOM会进行diff算法计算,来更新只需要被更新的DOM,而不是全部的重绘重构。与DOM操作相比,虚拟DOM是基于js计算的,而且是在内存中的,所以开销会很小。
流程图:
在这里插入图片描述

3.JSX语法及函数式组件

这里只做简单介绍

JSX语法
  • Javascript和XML结合的一种格式。最早 React 发明了JSX,利用HTML语法来创建虚拟DOM。JSX执行更快,因为它在编译为 JavaScript 代码后进行了优化。它是类型安全的,在编译过程中就能发现错误。使用JSX编写模板更加简单快速。
  • JSX语法需要babel插件转译为普通的HTML。
函数式组件
  • 可以把函数式组件想像成组件里的一个函数,入参是渲染上下文(render context),返回值是渲染好的HTML。
  • 函数式组件没有this,参数就是靠context来传递的,context完整属性可参照官方文档查询。
  • 特性:
    1.Stateless(无状态):组件自身是没有状态的
    2.Instanceless(无实例):组件自身没有实例,也就是没有this。
    export default {
    		name: 'functional-button',
    		functional: true,
    		render(createElement, context) {
    				return createElement('button', 'click me')
    		}
    }
    
context对象
  • props:提供所有prop的对象
  • children:VNode子节点的数组
  • slots:一个函数,返回了包含所有插槽的对象
  • scopedSlots:(2.6.0+)一个暴露传入的作用域插槽的对象,也以函数形式暴露普通插槽。
  • data:传递给组件的整个数据对象,作为 createElement的第二个参数传入组件,该对象可选
  • parent:对父组件的引用
  • listeners:(2.3.0+)一个包含了所有父组件为当前组件注册的事件监听器的对象。这是data.on的一个别名。
  • injections:(2.3.0+)如果使用了 inject 选项,则该对象包含了应当被注入的属性。
发布了56 篇原创文章 · 获赞 20 · 访问量 7364

猜你喜欢

转载自blog.csdn.net/qq_36826618/article/details/104220161
1.7