Vue核心知识-Vue的组件之render函数

render function

  • 类型(createElement: () => VNode) => VNode

  • 详细

    字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode

    如果组件是一个函数组件,渲染函数还会接收一个额外的 context 参数,为没有实例的函数组件提供上下文信息。

    Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数

组件中的 template 会被编译成 render function。

下例中,直接用 render function 代替 template,结果相同。

import Vue from 'vue'

const component = {
  name: 'comp',
  // template: `
  //   <div :style="style">
  //     <slot></slot>
  //   </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
    }, this.$slots.default)
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      },
      value: 'component value'
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span, this.$refs.comp.value)
  },
  template: `
    <div>
      <comp-one ref="comp">
        <span ref="span">{{value}}</span>
      </comp-one>
    </div>
  `,
  render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp'
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }
})

createElement

createElement,是 vue 虚拟 DOM 的概念,创建出来的并不是 html 节点,而是 VNode 的一个类,类似 DOM 结构的一个结构,并存在内存中,它会和真正的 DOM 进行对比,若发现需要更新的 DOM,才会去转换这部分 DOM 内容,并填到真正的 DOM 中,从而提高性能

createElement 可使用的属性

指令

传值 props

render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        props: { // props 传值
          props1: this.value
        }
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }

绑定事件

on

render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        on: { // 事件监听(一),这里是组件上监听,需要 $emit
          click: this.handleClick
        },
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }

nativeOn

render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        nativeOn: {
          click: this.handleClick
        }
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }

nativeOn 与 on 的区别

nativeOn 也是绑定到组件上,但是不需要组件发 $emit,它会自动绑定到这个组件的根节点的原生 DOM 上,如果本身就是原生 DOM,直接绑定。

slot

// 组件中
render (createElement) {
    return createElement('div', {
      style: this.style,
      on: {
        click: () => { this.$emit('click') }
      }
    }, [
      this.$slots.header, // 通过 $slot拿到 header,如果没命名就是 default
      this.props1
    ])
  }
// new Vue()
[
    createElement('span', {
        ref: 'span',
        slot: 'header' // 指定具名插槽
    }, this.value)
]

domProps

类似原生 DOM 操作,把 span 覆盖掉了。

[
        createElement('span', {
          ref: 'span',
          slot: 'header',
          domProps: {
            innerHTML: '<span>345</span>'
          }
        }, this.value)
      ]

attrs

给 span 加一个 id。

[
        createElement('span', {
          ref: 'span',
          slot: 'header',
          // domProps: {
          //   innerHTML: '<span>345</span>'
          // }
          attrs: {
            id: 'test-id'
          }
        }, this.value)
      ]

等等

总结

写组件的方式

  • template
  • render function
  • jsx
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 10,496评论 0 29
  • 深入响应式 追踪变化: 把普通js对象传给Vue实例的data选项,Vue将使用Object.defineProp...
    冥冥2017阅读 10,316评论 6 16
  • vue笔记 一.vue实例 vue的生命周期 beforeCreate(创建前), created(创建后), b...
    秋殇1002阅读 4,712评论 0 1
  • 文章作者:Tyan博客:noahsnail.com | CSDN | 简书 1. 动机 今天看MXNet的gluo...
    SnailTyan阅读 13,168评论 0 3
  • 夏末秋初是一个多雨的季节,天还蒙蒙亮,外面就飘起了细雨。顾暖暖揉揉了凌乱的头发,脑袋里突然出现了要逃掉今天的早自习...
    蜗小懒的小公举阅读 2,271评论 0 1

友情链接更多精彩内容