Iview: Table 组件的render函数,不能渲染非全局的自定义组件

Created on 25 Apr 2017  ·  3Comments  ·  Source: iview/iview



iView 版本号

2.0.0-rc.10

操作系统/浏览器 版本号

macOS/Chrome 57

Vue 版本号

2.2.6

能够复现问题的在线示例(bug 相关不提供在线示例将直接 close)


<template>
    <Table :columns="columns" :data="list">
    </Table>
</template>
<script>
import MyBtn from 'common/MyBtn.vue';

export default {
    components: {
        MyBtn
    },

    data() {
        return {
            columns: [{
                title:"操作",
                render(row, column, index){
                    return `<my-btn></my-btn>`;
                }
            }],

            list: [{}, {}, {}]
        }
    }
}
</script>

复现步骤

问题现象,以及你期望的结果是怎样的?

按这种方式使用,会报以下错误:

[Vue warn]: Unknown custom element: <my-btn> - did you register the component correctly? For recursive components, make sure to provide the "name" option. 
(found in <Root>)

即找不到自定义的组件。

期望的结果是能够在render中使用自定义组件,且自定义组件无需通过 Vue.component 的方式挂载到全局。

你估计可能的原因是什么(选填)?

看了下table组件的源码,是这么处理render的:

table/cell.vue

compile () {
    if (this.column.render) {
        const $parent = this.context;
        const template = this.column.render(this.row, this.column, this.index);
        const cell = document.createElement('div');
        cell.innerHTML = template;

        this.$el.innerHTML = '';
        let methods = {};
        Object.keys($parent).forEach(key => {
            const func = $parent[key];
            if (typeof(func) === 'function' && (func.name  === 'boundFn' || func.name === 'n')) {
                methods[key] = func;
            }
        });
        const res = Vue.compile(cell.outerHTML);
        // todo 临时解决方案
        const component = new Vue({
            render: res.render,
            staticRenderFns: res.staticRenderFns,
            methods: methods,
            data () {
                return $parent._data;
            }
        });
        component.row = this.row;
        component.column = this.column;

        const Cell = component.$mount();
        this.$refs.cell.appendChild(Cell.$el);
    }
}

其中这里在创建组件时并没有把父组件的components传递进来

const component = new Vue({
    render: res.render,
    staticRenderFns: res.staticRenderFns,
    methods: methods,
    data () {
        return $parent._data;
    }
});

貌似改成这样就可以了:

const component = new Vue({
    render: res.render,
    staticRenderFns: res.staticRenderFns,
    methods: methods,
    data () {
        return $parent._data;
    },
    components: $parent.$options.components
});

相关问题

https://github.com/iview/iview/issues/651

Most helpful comment

@voskresla

import customCom from 'xxx.vue'

render:  (h) => {
    return h(customCom)
}

All 3 comments

Thanks.

is it still actual ? in 2.0.0-rc.18 i still can't use custom component in Poptip render?

{
          title: '#',
          key: 'action',
          render: (h,params) => {
            return h('Poptip', {
              props: {
                trigger: 'hover',
              }
            },
            [
              h('div',{
                slot: 'content'
              },[
                h('my-component')
              ]),
              h('Badge', {
                props: {
                  count: params.row.comments.length
                },
                style: {
                  display: params.row.comments.length > 0 ? '' : 'none'
                }
              }, [
                h('Icon', {
                  props: {
                    type: 'chatbox',
                    size: '32px'
                  }
                })
              ]),
            ])
          }
        }

@voskresla

import customCom from 'xxx.vue'

render:  (h) => {
    return h(customCom)
}
Was this page helpful?
0 / 5 - 0 ratings