Vue Render函数

一. 前景介绍

  1. 起源
    vue.js 2.0 与 react 采用了相同的方案:在dom之上增加一个抽象层来解决渲染效率问题,这就是虚拟dom。
  2. 虚拟dom
    虚拟dom其实就是普通的JavaScript对象,访问JavaScript对象自然比访问真实的dom快得多。vue在更新到真实dom之前,会比较更新前后虚拟dom结构中的差异部分,然后采用异步更新队列的方式,将差异化的部门更新到真实的dom中,从而减少了页面渲染次数,提高了页面渲染效率。

二 . 函数介绍

  1. 简单示列
<script>
import Approval from "./comon/ApprovalNode.vue";

export default {
  name: "ProcessTree",
   components: {
    Approval,
  },
  data() {
    return {
     
    };
  },
  computed: {
   
  },
  render(createElement) {
    return createElement(
    "Approval", 
    { class: { _root: true }, ref: "_root" },
    [
    createElement('h1','一则头条'),
    createElement('div',{ style: { textAlign: center }, ref: "_refh" })
    ]
    );
  },
  methods: {

  }
}
</script>

<style lang="scss" scoped>
._root {
  margin: 0 auto;
  
  div {
    box-sizing: content-box;
  }
}
</style>
  1. 参数介绍
    第一个参数:必填;渲染的标签名,可以为自定义组件,也可以为html原生元素 形式 {String | Object | Function}
    第二个参数:可选;渲染标签的一些常用属性 形式为 { Object }
    第三个参数:可选;用于生成渲染标签的一些子节点 形式为 { String | Object }

三. 函数常用属性介绍

// @returns { Vnode }
createElement(
  // ------------------- 第一个参数 -------------------
  // {String | Object | Function}
  // 一个html标签名、组件选项对象,或者解析上述任何一个async函数
  'div',
  
  // ------------------- 第二个参数 -------------------
  // { Object }
  // 模板元素对应的数据对象
  {
      // 与 v-bind:class类似
     'class': {
     	foo: true,
     	bar: false
     },
     // 与 v-bind:style类似
     'style': {
     	color: 'red',
     	fontSize: '12px'
     },
     // 普通的html属性
     attrs: {
     	id: 'foo'
     },
     // 组件prop
     props: {
     	myProp: 'bar'
     },
     // 这个其实就是子组件的dom属性
     domProps: {
		innerHTML: 'baz'
     },
     // 在 'on' 属性内的事件监听器
     // 但不支持如 'v-on:keyup.enter' 这样的修饰符
     // 需要在处理函数中手动检查keyCode
     // this.insertNode 和 this.delNode 为 methods 内的函数方法
     on: {
     	 insertNode: (type) => this.insertNode(type),
     	 delNode: () => this.delNode(node),
     },
     // 仅用于组件,用于监听原生事件,而不是内部使用的vm.$emit触发的自定义事件
     nativeOn: {
		click: this.nativeClickHandler
     },
     // 自定义指令。
     directives:[{
		name: 'my-custom-directive',
		value: '2',
		expression: '1 + 1',
		arg: 'foo',
		modifiers: {
			bar: true
        }
     }],
     // 作用域插槽的格式为
     // { name: props => Vnode | Array }
     scopedSlots: {
		default: props => createElement('span', props.text)
     },
     // 如果组件是其它组件的子组件,需为插槽指定名称
     slot: 'name-of-solt',
     // 其它顶层属性
     key: 'myKey',
     ref: 'myRef',
     // 如果在render函数中给多个元素相同的ref名,则 $refs.myRef 会被渲染成一个数组
     // 为false表示:$refs.myRef 取到的是最后一个元素或组件
     refInFor: false,
  },
  
   // ------------------- 第三个参数 -------------------
   // { String | Object }
   // 子虚拟节点(VNode),由createElement构建而成
   [
	 createElement('h1','一则头条'),
	 createElement(MyComponet,{
		props: {
			someProp: 'foobar'
        }
     })
   ]
)

简单来说:createElement 函数的第一个参数是要创建的元素节点的名字(String)或者组件名(Object);第二个参数是渲染元素的属性集合(包够原生的普通属性、prop、事件属性、自定义指令),以对象形式给出 { Object };第三个参数是子节点的集合,以数组形式给出

官方介绍:https://cn.vuejs.org/v2/api/#render

四. 使用示列
替代v-if 和v-for

<ul v-if="items.length">
     <li v-for="(item, index) in items" :key="'li' + index"></li>
</ul>

render函数

 // props: ['items'],
 props: {
	type: Array,
	default: []
 },
 render(createElement) {
    if (this.items.length > 0) {
      return createElement(
        "ul",
        this.items.map((item, index) => {
          return createElement("li", {
            domProps: {
              innerHTML: item.name,
            },
            key: "li" + index,
          });
        })
      );
    } else {
      return createElement("p", "No items found");
    }
  },

你可能感兴趣的:(VUE,vue.js,render)