Учитывая объект 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>
Я пытаюсь создать небольшую оболочку VueJS вокруг библиотеки 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>
Я начал реализовывать это следующим образом:
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.info(row);
}
}
};
</script>
DataTableRow.vue
<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 ""; }
};
CustomEvent может всплывать мимо <tbody> и быть пойманным элементом DataTableуспешно (обход ограничения VueJS, что вы не можете прослушивать события в слотах)Мое событие дает мне массив объектов VNode. В моем ряду по одному VNode на столбец. В 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 ускользает от меня. Я пробовал бегло просмотреть документацию VueJS, и я попробовал погуглить, но без кубиков. Я попытался вручную передать функцию createElement (параметр, переданный методу render), но это вызвало ошибку. Как я могу попросить VueJS отобразить VNode, не вставляя результат в DOM?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я столкнулся с той же проблемой, желая сделать в основном то же самое с шаблоном деталей строки для DataTables.net.
Одним из решений может быть создание универсального компонента, отображающего VNode, и его программная реализация. Вот как я настраиваю динамическую строку деталей, которую я вставляю с помощью API-интерфейса datatable row.child().
RenderNode.js
export default {
props: ['node'],
render(h, context) {
return this.node ? this.node : ''
}
}
Datatables.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()
Вы должны определить свои компоненты следующим образом:
import {createApp} from 'vue';
import {defineAsyncComponent} from "vue";
createApp({
components: {
'top-bar': defineAsyncComponent(() => import('@Partials/top-bar'))
}
}).mount("#app")