目录↑

vue createElement与elementUI中表头修改

By blockXun

vue $createElement

Vue推荐在大多数情况下用模板来创建你的 HTML(template中写dom)。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。

createElement在正常开发下是一个不太常用的函数,他可以创建虚拟dom(VNode)

createElement参数

createElement(
    // {String | Object | Function}
    // 一个 HTML 标签名、组件选项对象,或者
    // resolve 了上述任何一种的一个 async 函数。必填项。
    'div',

    // {Object}
    // 一个与模板中属性对应的数据对象。可选。
    {
        // (详情见下一节)
    },

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

在官方文档中,createElement可以接收三个参数

  • {String | Object | Function} 标签名称
  • Object 节点上的属性,样式,事件等内容(下面会详细列出具体写法)
  • {String | Array | createElement()} 存储节点中的子节点或内容,如果有多个用数组表示

第二个参数的内容

{
    // 与 `v-bind:class` 的 API 相同,
    // 接受一个字符串、对象或字符串和对象组成的数组
    class: {
        foo: true,
        bar: false
    },
    // 与 `v-bind:style` 的 API 相同,
    // 接受一个字符串、对象,或对象组成的数组
    style: {
        color: 'red',
        fontSize: '14px'
    },
    // 普通的 HTML attribute(属性)
    attrs: {
        id: 'foo'
    },
    // 组件 prop (接收数据(<my-component :myProp="data" />))
    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
            }
        }
    ],
    // 作用域插槽的格式为
    // { name: props => VNode | Array<VNode> }
    scopedSlots: {
        default: props => createElement('span', props.text)
    },
    // 如果组件是其它组件的子组件,需为插槽指定名称
    slot: 'name-of-slot',
    // 其它特殊顶层属性
    key: 'myKey',
    ref: 'myRef',
    // 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
    // 那么 `$refs.myRef` 会变成一个数组。
    refInFor: true
}

复制于官方文档

使用createElement创建的组件的简单示例

import Vue from 'vue';
Vue.component('comp',{
    render(h) {
        return h('div',{
        style: {
            background: 'red',
        },
        on: {
            click: this.compClick
        }
        },'aaaaaaaaaaaaaaa')
    },
    methods: {
        compClick(e) {
            console.log(111111111111)
        }
    }
})

待完善

  1. 在vue的createElement源码中,后两个参数的具体用途
export function createElement (
    context: Component,
    tag: any,
    data: any,
    children: any,
    normalizationType: any,
    alwaysNormalize: boolean
): VNode | Array<VNode> {
    if (Array.isArray(data) || isPrimitive(data)) {
        normalizationType = children
        children = data
        data = undefined
    }
    if (isTrue(alwaysNormalize)) {
        normalizationType = ALWAYS_NORMALIZE
    }
    return _createElement(context, tag, data, children, normalizationType)
}

elementUI中表头修改

在用elementUI + vue制作表格时,可能会遇需求是 把表头修改成不止简单的string类型

比如下面这个例子,需求在表头中添加一个点击弹出的弹框提示

需求a
and
需求b

这时就需要使用tablerender-header方法配合组件<el-popover>来实现

render-header方法

| render-header | 列标题 Label 区域渲染使用的 | Function(h, { column, $index }) |

render-header方法返回的参数中,h的用法和createElement一样


<template>
......
    <el-table-column :render-header="columnRenderer">
......
<template/>
<script>
......
columnRenderer(h, { column, $index }) {
      return [
        '表头', 
        h(
          'el-popover',
          {
            props: {
              content: '这是弹出的内容',
              placement: 'top',
              effect: "light",
            },
          },
          [
            h('span', {
              class: {
                'el-icon-question': true // el中 问号 iconfont的class
              },
              slot: 'reference'
            })
          ]
        )
      ]
    },
......
</script>

或者使用组件<Tooltip>配合


<template>
......
    <el-table-column :render-header="columnRenderer">
......
<template/>
<script>
......
columnRenderer(h, { column, $index }) {
      return [
        '表头', 
        h(
          'el-tooltip',
          {
            props: {
              content: '这是弹出的内容',
              placement: 'top',
            },
          },
          [
            h('span', {
              class: {
                'el-icon-question': true // el中 问号 iconfont的class
              },
            })
          ]
        )
      ]
    },
......
</script>