在kotlin js项目中使用Vaadin组件

在kotlin js项目中使用Vaadin组件,vaadin,kotlin-js,Vaadin,Kotlin Js,这个问题是关于使用Kotlin前端插件的Kotlin JS项目的 我想使用来自的一些UI组件 关于这一点,我有两个问题: (1) 在Kotlin JS中包含web组件的最佳方式是什么 =>有关我的完整代码,请参阅下面的源代码链接。总括而言,有关详情如下: build.gradle.kts kotlinFrontend { npm { dependency("@vaadin/vaadin-grid") } } ... customElements.define(G

这个问题是关于使用Kotlin前端插件的Kotlin JS项目的

我想使用来自的一些UI组件

关于这一点,我有两个问题:

(1) 在Kotlin JS中包含web组件的最佳方式是什么

=>有关我的完整代码,请参阅下面的源代码链接。总括而言,有关详情如下:

build.gradle.kts

kotlinFrontend {
    npm {
        dependency("@vaadin/vaadin-grid")
    }
}
...
customElements.define(GridElement.is, GridElement);
export { GridElement };
vaadin.grid.Imports.kt

@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
external class GridElement {
    companion object
}
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 ?? */
}
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule

package vaadin.grid

import org.w3c.dom.HTMLElement

abstract external class GridElement : HTMLElement {
    var items: Array<*> = definedExternally
}
为什么是
伴生对象
?我需要它来解决问题(见下文)

foo.kt

@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
external class GridElement {
    companion object
}
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 ?? */
}
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule

package vaadin.grid

import org.w3c.dom.HTMLElement

abstract external class GridElement : HTMLElement {
    var items: Array<*> = definedExternally
}
console.log
是我想要避免的丑陋的解决方法。如果我不使用GridElement做任何事情,那么它就不包括在我的包中

vaadin_grid
DSL被定义为一个与代码无关的自定义kotlinx.html标记

(2) 我希望尽可能保持代码的类型化,以避免
asDynamic
,但是当我将
HTMLElement
强制转换为Vaadin元素时,我会得到ClassCastException(因为
GridElement
未定义的

例如,我想写这样的东西:

val grid : GridElement = document.querySelector("#grid") as GridElement
grid.items = ... // vs grid.asDynamic().items which does work
下面是我如何定义外部GridElement的

vaadin/button/Imports.kt

@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
external class GridElement {
    companion object
}
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 ?? */
}
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule

package vaadin.grid

import org.w3c.dom.HTMLElement

abstract external class GridElement : HTMLElement {
    var items: Array<*> = definedExternally
}

要运行:

从git回购协议的根目录:

./gradlew 05-kt-frontend-vaadin:build && open 05-kt-frontend-vaadin/frontend.html
我找到了答案

关于第一个问题

(1) 在Kotlin JS中包含web组件的最佳方式是什么

我使用
require(…)

(归功于某人的回答)

(2) 我希望尽可能地保持代码的类型化,以避免代码的动态性

我没有导入
@vaadin/vaadin grid
,而是导入实际公开元素的文件。然后它似乎起作用了,我甚至可以将泛型添加到我的GridElement中:

@file:JsModule("@vaadin/vaadin-grid/src/vaadin-grid")
@file:JsNonModule

package vaadin.grid

import org.w3c.dom.HTMLElement

abstract external class GridElement<T> : HTMLElement {
    var items: Array<out T> = definedExternally
}