这个问题是关于一个使用 Kotlin 前端插件的 Kotlin JS 项目。
我想使用Vaadin 组件库中的一些 UI 组件。
我对此有两个问题:
(1) 在 Kotlin JS 中包含 Web 组件的最佳方式是什么
=> 对于我的完整代码,请参阅下面的源链接。总而言之,相关细节是:
构建.gradle.kts
kotlinFrontend {
npm {
dependency("@vaadin/vaadin-grid")
}
}
vaadin.grid.Imports.kt
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
external class GridElement {
companion object
}
为什么companion object
?我需要它来解决问题(见下文)。
foo.kt
fun main() {
document.getElementById("container")!!.append {
vaadin_grid {
attributes["id"] = "grid"
}
}
initUI()
}
fun initUI() {
// Force the side-effects of the vaadin modules. Is there a better way?
console.log(GridElement)
val grid = document.querySelector("#grid") /* ?? as GridElement ?? */
}
这console.log
是我想避免的丑陋的解决方法。如果我不对GridElement做任何事情,那么它就不会包含在我的捆绑包中。
vaadin_grid
DSL 被定义为一个自定义的 kotlinx.html 标签,它是不相关的代码。
(2) 我希望尽可能避免键入代码,asDynamic
但是当我将其HTMLElement
转换为 Vaadin 元素时,我得到 ClassCastExceptions (因为GridElement
is undefined
)。
例如我想写这样的东西:
val grid : GridElement = document.querySelector("#grid") as GridElement
grid.items = ... // vs grid.asDynamic().items which does work
这是我定义外部 GridElement 的方式
vaadin/按钮/Imports.kt
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
import org.w3c.dom.HTMLElement
abstract external class GridElement : HTMLElement {
var items: Array<*> = definedExternally
}
构建/node_modules/@vaadin/vaadin-grid/src/vaadin-grid.js
...
customElements.define(GridElement.is, GridElement);
export { GridElement };
跑步:
从 git repo 的根目录:
./gradlew 05-kt-frontend-vaadin:build && open 05-kt-frontend-vaadin/frontend.html