vue render函数

render函数比template模板更加接近编辑器。使用虚拟dom渲染节点可以提升性能,通过createElement(h)来创建dom节点。template也是被解析成虚拟dom。(虚拟dom实际是一个JavaScript对象)

computed属性实在vnode虚拟节点created()生命周期执行完后,lazy的模式调用,就是什么时候需要这个计算属性,什么时候去调用computed,而render则是一个主动渲染的过程,首次执行是在beforeMount和mounted两个生命周期之间。

下面说一说最重要的createElement函数:

第一个参数:HTML标签名,组件或者函数都可以(必须)类型:String/Object/Function

第二个参数:数据对象(可选)类型:Object 

ex:

{
  // 和`v-bind:class`一样的 API
  'class': {
    foo: true,
    bar: false
  },
  // 和`v-bind:style`一样的 API
  style: {
    color: 'red',
    fontSize: '14px'
  },
  // 正常的 HTML 特性
  attrs: {
    id: 'foo'
  },
  // 组件 props
  props: {
    myProp: 'bar'
  },
  // DOM 属性
  domProps: {
    innerHTML: 'baz'
  },
  // 事件监听器基于 `on`
  // 所以不再支持如 `v-on:keyup.enter` 修饰器
  // 需要手动匹配 keyCode。
  on: {
    click: this.clickHandler
  },
  // 仅对于组件,用于监听原生事件,而不是组件内部使用
  // `vm.$emit` 触发的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
  // 赋值,因为 Vue 已经自动为你进行了同步。
  directives: [
    {
      name: 'my-custom-directive',
      value: '2',
      expression: '1 + 1',
      arg: 'foo',
      modifiers: {
        bar: true
      }
    }
  ],
  // Scoped slots in the form of
  // { name: props => VNode | Array<VNode> }
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
  // 如果组件是其他组件的子组件,需为插槽指定名称
  slot: 'name-of-slot',
  // 其他特殊顶层属性
  key: 'myKey',
  ref: 'myRef'
}

  

第三个参数:子节点(可选)类型:String/Array

看例子:

export default{
  render(h){
    const menu_items = ['首页','搜索','分类','系统'];
    return h('ul',{
      {
         class:'class-name'
      },
      menu_items.map(item = > h('li',item))
    })
  }  
}

相当于

<template>
  <ul>
    <li v-for="item in menu_items">
      {{ item }}
    </li>
  </ul>
</template>

  

实际例子使用

export default {
 props: {
  type: {
   type: String,
   default: 'normal'
  },
  text: {
   type: String,
   default: 'normal'
  }
 },
 computed: {
  tag() {
   switch (this.type) {
    case 'success':
     return 1;
    case 'danger':
     return 2;
    case 'warning':
     return 3;
    default:
     return 1;
   }
  }
 },
/**
render() {
 return (
  <div
   class={{
    btn: true,
    'btn-success': this.type === 'success',
    'btn-danger': this.type === 'danger',
    'btn-warning': this.type === 'warning'
   }}
   onClick={this.handleClick}>
   {this.text}
  </div>
 );
},**/
 render(h) {
  return h('div', {
   class: {
    btn: true,
    'btn-success': this.type === 'success',
    'btn-danger': this.type === 'danger',
    'btn-warning': this.type === 'warning'
   },
   domProps: {
    innerText: this.text
   },
   on: {
    click: this.handleClick
   }
  });
 },
 methods: {
  handleClick() {
   console.log('-----------------------');
   console.log('do something');
  }
 }
};

<Button type="danger" text="test"></Button>

  

posted @ 2019-02-13 16:57  maomao^_^  阅读(442)  评论(0编辑  收藏  举报