vue-12-渲染函数 & JSX

render()

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(//VNode,虚拟dom
      'h' + this.level,   // tag name 标签名称
      this.$slots.default // 子组件中的阵列
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})
<anchored-heading :level="1">Hello world!</anchored-heading>
// @returns {VNode}
createElement(
  // {String | Object | Function}
  // 一个 HTML 标签字符串,组件选项对象,或者一个返回值类型为 String/Object 的函数,必要参数
  'div',
  
  {
   // {Object}
  // 一个包含模板相关属性的数据对象
  // 这样,您可以在 template 中使用这些属性。可选参数。
  },

  // {String | Array}
  // 子节点 (VNodes),由 `createElement()` 构建而成,
  // 或使用字符串来生成“文本节点”。可选参数。
  [
    '先写一些文字',
    createElement('h1', '一则头条'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)

组件树中的所有 VNodes 必须是唯一的,如果需要重复

render: function (createElement) {
  return createElement('div',
    Array.apply(null, { length: 20 }).map(function () {
      return createElement('p', 'hi')
    })
  )
}

render中 不能用模板中可以使用的v-for,v-if,v-model而是用原生JS实现

v-model在render中的实现:
render: function (createElement) {
  var self = this
  return createElement('input', {
    domProps: {
      value: self.value
    },
    on: {
      input: function (event) {
        self.value = event.target.value
        self.$emit('input', event.target.value)
      }
    }
  })
}

事件修饰符

Modifier(s)    Prefix
.passive  &
.capture !
.once ~
.capture.once ~!
.once.capture ~!

对于其他的修饰符,前缀不是很重要,因为你可以在事件处理函数中使用事件方法:

Modifier(s)Equivalent in Handler
.stop event.stopPropagation()
.prevent event.preventDefault()
.self if (event.target !== event.currentTarget) return
Keys:
.enter.13
if (event.keyCode !== 13) return (change 13 to another key code for other key modifiers)
Modifiers Keys:
.ctrl.alt.shift.meta
if (!event.ctrlKey) return (change ctrlKey to altKeyshiftKey, or metaKey, respectively)

插槽

render: function (createElement) {
  // `<div><slot></slot></div>`
  return createElement('div', this.$slots.default)//静态内容
}
render: function (createElement) {
  // `<div><slot :text="msg"></slot></div>`
  return createElement('div', [
    this.$scopedSlots.default({//用作函数
      text: this.msg
    })
  ])
}
向子组件传递
render (createElement) {
  return createElement('div', [
    createElement('child', {
      // pass `scopedSlots` in the data object
      // in the form of { name: props => VNode | Array<VNode> }
      scopedSlots: {
        default: function (props) {
          return createElement('span', props.text)
        }
      }
    })
  ])
}

jsx:

import AnchoredHeading from './AnchoredHeading.vue'
new Vue({
  el: '#demo',
  render (h) {//将 h 作为 createElement 的别名
    return (
      <AnchoredHeading level={1}>
        <span>Hello</span> world!
      </AnchoredHeading>
    )
  }
})

函数式组件:标记组件为 functional,这意味它是无状态 (没有 data),无实例 

Vue.component('my-component', {
  functional: true,
  // 为了弥补缺少的实例
  // 提供第二个参数作为上下文
  render: function (createElement, context) {
    // ...
  },
  // Props 可选
  props: {
    // ...
  }
})
函数式组件需要的一切都是通过上下文传递,包括:
props:提供 props 的对象
children: VNode 子节点的数组
slots: slots 对象
data:传递给组件的 data 对象
parent:对父组件的引用
listeners: (2.3.0+) 一个包含了组件上所注册的 v-on 侦听器的对象。这只是一个指向 data.on 的别名。
injections: (2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的属性
this.$slots.default 更新为 context.children,之后this.level 更新为 context.props.level



原文地址:https://www.cnblogs.com/avidya/p/7641754.html