我绝对不是Kotlin的新手。我试图通过 Kotlin 在后端创建一个简单的对象,并将其放在前端 Vuejs 上。我该怎么做(这是HeaderBar.kt
的原始代码,我的所有尝试都被编译器拒绝了):
object HeaderBar {
val computed = object {
fun items(): Array<Item> {
items.add(Item(
"NY",
"Bill"
))
return items
}
}
data class Item(
val city: String,
val name: String
)
}
在 Kotlin 一边?
并在
items
上获取HeaderBar.vue
。我不确定,但是我这样做是: <template>
<div class="main-header">
<div v-for="item in items" class="items">
<span class="city">{{item.city}}</span>
<span class="name">{{item.name}}</span>
</div>
</div>
<template>
<script>
export default path.to.HeaderBar
</script>
最佳答案
首先,这不是一个简单的问题。 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<String>) {
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<String, Any>.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<Any>).toJs()
else -> throw RuntimeException("value has invalid type")
}
}
return result
}
fun List<Any>.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
}
我写了一些函数
toJs
,它将Kotlin对象转换为Js对象。从理论上讲,您可以使用JSON序列化来简化此过程,或者使用其他更简单的解决方案(如果存在)。Vue.kt
@file:JsModule("vue")
package vue_test
@JsName("default")
external open class Vue(init: dynamic)
在此文件中,我们只有Vue声明。
index.html
<!DOCTYPE html>
<html>
<head>
<title>Test project</title>
</head>
<body class="testApp">
<h1>Kotlin-Js test</h1>
<div id="app">
<div class="main-header">
<div v-for="item in items" class="items">
<span class="city">{{item.city}}</span>
<span class="name">{{item.name}}</span>
</div>
</div>
</div>
<script type="text/javascript" language="JavaScript" src="frontend.bundle.js"></script>
</body>
</html>
Buldle是由webpack创建的,我将此脚本放到最下面,因为只有在所有必要的html标签已经存在时才需要
Vue
来开始对其进行操作。我的带有kotlin-frontend插件和kotlin-js插件的build.gradle文件:
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中做到这一点。希望这能够帮到你!
要使用dev bundle启动项目,请运行以下命令:
gradle build webpack-run
,然后在浏览器中打开http://localhost:8080
。停止测试运行命令:
gradle webpack-stop
关于vue.js - 如何将数据添加到Kotlin对象并在Vuejs页面上获取它,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47884245/