如何在KotlinJS中生成含`this.field=value`的函数及适配Riot标签
KotlinJS 适配 Riot 标签函数的规范实现方式
我之前也碰到过类似的场景,一开始靠val self = js("this")临时解决,后来摸索出两种更顺手的实现方式,分享给你:
一、直接生成含this.field=value的原生JS函数
如果想让Kotlin输出你需要的原生JS函数结构,既可以用Kotlin语法结合dynamic类型实现,也可以直接还原JS写法,两种方式都能满足需求:
方式1:Kotlin语法结合JS上下文
val sampleTag = js("function(opts) {}").apply { // 直接给函数上下文绑定属性 this.name = "sample" this.message = "init-message" // 注意:Kotlin的lambda会捕获外部上下文,所以事件方法里要用js("this")获取Riot运行时的标签实例 this.onCreate = fun(opts: dynamic) { js("this").message = opts.message } this.click = fun() { js("this").message = "Clicked!" } }
这段代码会生成你需要的JS函数,apply块里的this对应JS函数的上下文,事件方法里的js("this")则确保指向Riot的标签实例。
方式2:直接嵌入原生JS代码
如果觉得上面的写法有点杂糅,也可以用多行字符串直接写JS,可读性反而更高:
val sampleTag = js(""" function(opts) { this.name = "sample"; this.message = "init-message"; this.onCreate = function(opts) { this.message = opts.message; }; this.click = function() { this.message = "Clicked!"; }; } """)
二、更规范的Kotlin风格适配方案
如果想尽量用Kotlin的面向对象逻辑封装标签代码,避免直接写JS,可以用类来包裹所有标签逻辑,再转换成Riot兼容的函数:
// 用Kotlin类封装标签的属性与方法,类型更安全 class SampleTag { var name = "sample" var message = "init-message" fun onCreate(opts: dynamic) { message = opts.message } fun click() { message = "Clicked!" } } // 转换成Riot需要的标签函数 fun createSampleTag(): dynamic = js("function(opts) { Object.assign(this, tagInstance); if (this.onCreate) this.onCreate(opts); }").apply { this.tagInstance = SampleTag() }
核心逻辑是用Object.assign把Kotlin类实例的属性和方法复制到Riot的标签实例(即函数内的this)上,同时自动触发onCreate初始化钩子。这种方式的好处是标签逻辑都在Kotlin类里维护,后续扩展生命周期钩子也只需要在类里添加对应方法即可。
内容的提问来源于stack exchange,提问作者Freewind
相关产品推荐
相关产品推荐

