代码之家  ›  专栏  ›  技术社区  ›  stevendesu

VueJS呈现VNode

  •  2
  • stevendesu  · 技术社区  · 7 年前

    给出一个VueJS VNode 对象,如何获取在呈现时生成的HTML元素?

    例如。:

    > temp1
    VNode {tag: "h1", data: undefined, children: Array(1), text: undefined, elm: undefined, …}
    > temp1.children[0]
    VNode {tag: undefined, data: undefined, children: undefined, text: "Test", elm: undefined, …}
    > doSomething(temp1)
    <h1>Test</h1>
    

    目标

    DataTables.net 图书馆。

    要模拟标记中HTML表的行为,我需要如下内容:

    <datatable>
        <thead>
            <tr>
                <th>Name</th>
                <th>Age</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody>
            <datatable-row v-for="person in people">
                <td>{{ person.name }}</td>
                <td>{{ person.age }}</td>
                <td>{{ person.salary }}</td>
            </datatable-row>
        </tbody>
    </datatable>
    

    到目前为止我所做的

    我已经开始执行如下操作:

    数据表.vue

    <template>
        <table ref="table" class="display table table-striped" cellspacing="0" width="100%">
            <slot></slot>
        </table>
    </template>
    
    <script>
    /* global $ */
    export default {
        data: () => ({
            instance: null
        }),
        mounted() {
            this.instance = $(this.$refs.table).dataTable();
            this.$el.addEventListener("dt.row_added", function(e) {
                this.addRow(e.detail);
            });
        },
        methods: {
            addRow(row) {
                // TODO <-----
                console.log(row);
            }
        }
    };
    </script>
    

    <script>
    /* global CustomEvent */
    export default {
        mounted() {
            this.$nextTick(() => {
                this.$el.dispatchEvent(new CustomEvent("dt.row_added", {
                    bubbles: true,
                    detail: this.$slots.default.filter(col => col.tag === "td")
                }));
            });
        },
        render() { return ""; }
    };
    

    目前的情况:

    • 当页面加载时,数据表被初始化。所以列标题的格式是正确的,我在左下角看到“显示0到0个条目”
    • 这个 CustomEvent 能够从 <tbody> DataTable 要素 成功地 (避开VueJS中不能监听插槽上事件的限制)

    这是干什么的

    • 实际添加行

    V节点 V节点 每列在我的行。DataTables API有一个 addRow 可以这样调用的函数:

    this.instance.row.add(["col1", "col2", "col3"]);
    

    在我的例子中,我希望VNode呈现的结果元素是这个数组中的元素。

    var elems = [];
    for (var i = 0; i < row.length; i++)
        elems[i] = compile(row[i]);
    this.instance.row.add(elems);
    

    不幸的是 compile createElement 函数(传递给 render

    1 回复  |  直到 7 年前
        1
  •  3
  •   davidmdem    7 年前

    我遇到了同样的问题,希望对DataTables.net的行详细信息模板做基本相同的事情。

    一种解决方案是创建一个通用组件,该组件将 VNode 并以编程方式实例化。下面是我使用datatable的 row.child() 应用程序编程接口。

    export default {
        props: ['node'],
        render(h, context) {
            return this.node ? this.node : ''
        }
    }
    

    数据表.vue

    包括上面的渲染器组件

    import Vue from 'vue'
    import nodeRenderer from './RenderNode'
    

    实例化并装载呈现程序以获取编译的HTML

    // Assume we have `myVNode` and want its compiled HTML
    
    const DetailConstructor = Vue.extend(nodeRenderer)
    
    const detailRenderer = new DetailConstructor({
        propsData: {
            node: myVNode
        }
    })
    
    detailRenderer.$mount()    
    // detailRenderer.$el is now a compiled DOM element 
    row.child(detailRenderer.$el).show()