如何将数据添加到Kotlin对象并在Vuejs页面上获取

对于Kotlin我绝对是新手。 我试图在Kotlin的后端做一个简单的对象,并在前端Vuejs上获得它。 我怎么能这样做(这是HeaderBar.kt原始代码 ,我所有的尝试都被编译器拒绝):

  object HeaderBar { val computed = object { fun items(): Array { items.add(Item( "NY", "Bill" )) return items } } data class Item( val city: String, val name: String ) } 

在Kotlin方面?

并获取HeaderBar.vue上的items 。 我不确定,但是我是这样做的:

   
{{item.city}} {{item.name}}
export default path.to.HeaderBar

首先,这不是一个简单的问题。 Kotlin / Js不像Kotlin / Jvm那么成熟,所以有很多不是那么简单的任务。

首先,您需要以某种方式编译为JavaScript,然后您需要将Vue附加到kotlin / javascript代码。

Webpack可以使它更容易,所以我写一个简单的例子来向你展示如何在Kotlin中编写你的例子。

!警告!:下面的所有代码只是草稿(并且仅在演示中已经写过),所以在您的项目中特别谨慎地使用它!

让我们用下面的结构创建项目: 项目结构

Application.kt:

 package vue_test fun VueJs(init: VueContext.() -> Unit) = Vue(VueContext().apply(init)) class VueContext { var el: String = "" var data: dynamic = js("{}") } fun main(args: Array) { val app: dynamic = VueJs { el = "#app" data = mapOf("items" to listOf( Item("NY", "Bill"), Item("Test", "Test2") )).toJs() } } data class Item( val city: String, val name: String ) fun Map.toJs(): dynamic { val result: dynamic = object {} for ((key, value) in this) { when (value) { is String -> result[key] = value is List<*> -> result[key] = (value as List).toJs() else -> throw RuntimeException("value has invalid type") } } return result } fun List.toJs(): dynamic { val result: dynamic = js("[]") for (value in this) { when (value) { is String -> result.push(value) is Item -> { result.push(value.toJs()) } else -> throw RuntimeException("value has invalid type") } } return result } fun Item.toJs(): dynamic { val result: dynamic = object {} result["city"] = this.city result["name"] = this.name return result } 

我已经写了几个函数来把Kotlin对象转换成Js对象。 它理论上可以使用JSON序列化来简化这个,或者其他更简单的解决方案(如果存在的话)。

Vue.kt

 @file:JsModule("vue") package vue_test @JsName("default") external open class Vue(init: dynamic) 

在这个文件中,我们只有Vue声明。

的index.html

    Test project   

Kotlin-Js test

{{item.city}} {{item.name}}

Buldle是由webpack创建的,我已经把这个脚本放在了底部,因为Vue需要开始他的操作,只有所有必要的html标签已经存在。

我的build.gradle文件与kotlin-frontend插件和kotlin-js插件:

 buildscript { ext.kotlin_version = '1.2.10' repositories { mavenCentral() jcenter() maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } maven { url "https://repo.gradle.org/gradle/libs-releases-local" } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.21" } } group 'test' version '1.0-SNAPSHOT' apply plugin: 'kotlin-platform-js' apply plugin: 'org.jetbrains.kotlin.frontend' repositories { mavenCentral() } kotlinFrontend { sourceMaps = true npm { dependency("vue") } webpackBundle { port = 8080 bundleName = "frontend" contentPath = file('src/main/web') webpackConfigFile = project.projectDir.path + '/webpack.config.js' } } compileKotlin2Js { kotlinOptions.metaInfo = true kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js" kotlinOptions.sourceMap = true kotlinOptions.moduleKind = 'commonjs' kotlinOptions.main = "call" } kotlin { experimental { coroutines 'enable' } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" } 

settings.gradle

 rootProject.name = 'test-kotlin-vue' 

和最后一个文件,自定义webpack配置:

 var config = require('./build/WebPackHelper.js') var path = require('path') module.exports = { entry: config.moduleName, output: { path: path.resolve('./bundle'), publicPath: '/build/', filename: 'frontend.bundle.js' }, module: { rules: [] }, resolve: { modules: [path.resolve('js'), path.resolve('..', 'src'), path.resolve('.'), path.resolve('node_modules')], extensions: ['.js', '.css'], alias: { 'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1 } }, devtool: '#source-map' }; console.log(module.exports.resolve.modules); 

使用kotlin-frontend插件,你不能使用单独的webpack配置,但在这个例子中, Vue需要一个完整的版本来编译模板,所以需要在webpack中添加别名。 而我不知道如何在build.gradle中做到这一点。

希望对你有帮助!

要使用开发包启动项目,请运行以下命令: gradle build webpack-run ,然后在浏览器中打开http://localhost:8080

停止测试运​​行命令: gradle webpack-stop