前言

在Compose跨平台第一弹:体验Compose for Desktop 中,我们已经了解了Compose-jb以及如何使用Compose-jb开发简单的桌面端应用,第二弹,我们就来了解下如何使用Compose-jb开发Web应用。相信看完这一弹之后你会对Compose-jb有新的了解。

环境要求

与Compose For Desktop的环境要求一致。

开发流程

创建项目

同样的,我们打开IDEA创建Compose Multiplatform项目,选择Single plaform,不过这里我们选择Platform为Web平台,如下图所示。

创建好项目后,来看项目目录结构,如下图所示。

可以看到同样的在配置文件中指定了平台配置,这一点是比较重要的,便于以后我们在原有项目基础上添加配置。并且以后我们会发现,这个配置也不一定在根目录中的build文件中,所以我们需要知道配置的含义,这一点目前规划在后续的弹中会单独分享。

项目结构

在jsMain文件夹下Main文件通过renderComposable的rootElementId属性与index.html中的div标签绑定,从而将页面在web中显示。index.html代码截图如下所示。

Main.kt代码截图如下所示。

当我看到这段代码之后,我心里是慌的,Div?style?attrs?这都是什么玩意啊,学了Compose的我都不知道,这也能叫跨平台?

这是Compose for Web专门提供的一套DOM API,Div组件也是为Web实现的对应Composeable组件,通过attrs方法设置标签属性。所以这些代码,都是无法直接在Android或Desktop平台上复用的。所以,从这一点来讲使用Compose实现跨平台,目前存在严重的割裂问题,和Flutter相比还是有一定的差距。

运行程序(./gradlew jsBrowserRun),页面如下图所示。

这是项目默认实现的一个加减计数器的功能。接下来我们来添加自己的组件。

添加输入框

和开发Desktop一样,我们先来添加一个输入框,在Compose for Web中输入框采用Input组件

,代码如下所示:

renderComposable(rootElementId = "root") {Div {P {Input(type = InputType.Text) {}}P {Input(type = InputType.Password)}P {Button(attrs = {onClick {}}) {Text("Login")}}}
}

通过type属性指定输入框的类别分别为文字和密码,运行程序,结果如下图所示。

接着我们通过添加Text标签为输入框添加属性说明,修改部分的代码如下所示:

P {Text("用户名")Input(type = InputType.Text) {}
}
P {Text("密码")Input(type = InputType.Password)
}

再次运行程序,结果如下图所示。

嗯,挺丑的。上述代码我们在最外层使用Div包裹是为了便于为这块区域设置一些属性,比如我们设置背景色为蓝色,代码如下所示。

Div({style {backgroundColor(Color.blue)
}}){...
}

运行程序,结果如下所示。

好吧,更丑了… , Compose for Web 允许开发者基于 DSL 定义 Style 样式,但是到目前为止我的感觉是写的很累,感觉如果不会Web就无法写好Compose for Web,这叫哪门子的跨平台?

添加超链接

超链接直接使用A标签即可,比如这里我们添加一个用户隐私协议,代码如下所示。

P {A("https://www.baidu.com/") { Text("用户协议")}
}

运行程序,结果如下图所示。

如果想用Compose写好Web,我觉得最主要的是Style DSL,但是在这里我们没办法一一展示。需要我们在项目中去实战。接下来,我们来实现与Desktop一样的查询数据功能。

实现查询数据功能

本来打算仍然借用「wanandroid」中「每日一问」接口的,但是这个接口存在跨域问题,导致无法请求,所以我们这里将接口返回的json数据,定义为Api文件中的data变量,Ktor的使用方式是一样的,所以并不影响实际结果。

定义HttpUtil类并实现getData方法,代码如下所示。

class HttpUtil {/*** 获取数据*/suspend fun getData(): DemoReqData {val rockets = Json.decodeFromString<DemoReqData>(string = Api.data)return rockets}
}

在Desktop中我们可以直接在Main 文件中直接调用取数据的方法,但是这里不行,因为renderComposable下无法启动协程。所以这里我们定义一个DataSource类继承自CoroutineScope,同样定义一个loadData方法,代码如下所示。

class DataSource : CoroutineScope {private var job = Job()override val coroutineContext: CoroutineContextget() = jobprivate val _stateFlow = MutableStateFlow(DemoReqData())var stateFlow = _stateFlow.asStateFlow()fun loadData() {launch {_stateFlow.value = HttpUtil().getData()}}
}

这样我们可以在loadData方法中启动协程并调用HttpUtil中的getData方法,然后赋值给stateFlow,这一点得益于Flow 是 kotlinx 包下的组件,与平台无关。

最后,我们在Main中定义一个按钮,点击“请求数据”,然后将数据显示出来,代码如下所示。

renderComposable(rootElementId = "root") {val dataSource = DataSource()val data = dataSource.stateFlow.collectAsState()Button(attrs = {onClick {dataSource.loadData()}}) {Text("请求数据")}Div {repeat(data.value.data?.datas?.size ?: 0) {Div {P {Text("作者:" + data.value.data?.datas?.get(it)?.author)}P {Text("标题:" + data.value.data?.datas?.get(it)?.title)}P({style {height(1.px)backgroundColor(Color.red)}}) {}}}}
}

这里将作者信息与标题显示出来,为了效果明显添加了一个红色的横线,运行程序,点击“请求数据”,结果如下图所示。

这样我们就使用Compose实现了一个Web端简单的查询数据功能。

写在最后

Compose For Web 中提供了更贴近 HTML 风格的 Composable API,所以UI代码无法与Android或Desktop的UI代码直接复用。但是逻辑层的代码都是可以共用的,目前Google也在推进解决这样的“割裂”问题,从目前来看,Compose跨平台还有一定的路要走,我们将在后续的第N弹中持续探索…

作者:黄林晴
链接:https://juejin.cn/post/7187306464875118651

文末福利

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。


相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

二、源码解析合集


三、开源框架合集


欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

Compose跨平台第二弹:体验Compose for Web相关推荐

  1. Compose跨平台又来了,这次能开发iOS了

    /   今日科技快讯   / 近日,有消息称百度3月将推出ChatGPT风格服务.经百度确认,该项目名字确定为文心一言,英文名ERNIE Bot,三月份完成内测,面向公众开放. 目前,文心一言在做上线 ...

  2. 拿来吧你,Compose尝鲜初体验!

    前言 Compose 正式版在七月份的尾巴如期而至,我也写了一份 Compose 版本的项目,Demo其实比较简单. 地址:github.com/mCyp/Hoo. 这已经是它的第三个版本: 第一版: ...

  3. CSS 动画相关属性动态实例大全(82种),2023年祝福第二弹(送你一只守护兔)(下),守护兔源代码免费下载

    2023年春节祝福第二弹--送你一只守护兔(下) CSS 动画相关属性动态实例大全(82种).守护兔源代码免费下载 本文目录: 五.CSS3 动画相关属性实例大全 (1).CSS3的动画基本属性 (2 ...

  4. 开源 | 蚂蚁金服分布式中间件开源第二弹:丰富微服务架构体系

    小蚂蚁说: 数据.消息.微服务是蚂蚁金服自主研发的金融级分布式中间件 SOFA (Scalable Open Financial Architecture)的三大方向. 一个多月前,蚂蚁金服开源了 S ...

  5. MaxCompute - ODPS重装上阵 第二弹 - 新的基本数据类型与内建函数

    MaxCompute(原ODPS)是阿里云自主研发的具有业界领先水平的分布式大数据处理平台, 尤其在集团内部得到广泛应用,支撑了多个BU的核心业务. MaxCompute除了持续优化性能外,也致力于提 ...

  6. 与容器服务 ACK 发行版的深度对话第二弹:如何借助 hybridnet 构建混合云统一网络平面

    作者:若禾.昱晟.瑜佳 记者: 各位阿里巴巴云原生的读者朋友们大家好,欢迎再次来到探究身世之谜系列专访栏目,今天邀请来的还是大家的老朋友,『阿里云容器服务 ACK 发行版』,上次的访谈中它为我们介绍了 ...

  7. 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 3

    继上一次介绍了<神奇的六边形>的完整游戏开发流程后(可点击这里查看),这次将为大家介绍另外一款魔性游戏<跳跃的方块>的完整开发流程. (点击图片可进入游戏体验) 因内容太多,为 ...

  8. vue如何获取年月日_vue 学习笔记第二弹

    1. vue,学习第二弹! 1.x 版本中的 filterBy 指令,在2.x中已经被废除: filterBy - 指令 1 在 2.x 版本中手动实现筛选的方式: 筛选框绑定到 VM 实例中的 se ...

  9. compose应用_带有PostgreSQLDocker Compose for Spring Boot应用程序

    compose应用 在此博客文章中,您将学习如何使用PostgreSQL配置Spring Boot应用程序以与Docker Compose一起运行. 这篇博客文章涵盖: Spring Boot应用程序 ...

最新文章

  1. ExtJs grid合并单元格
  2. 前端面试题学习和总结
  3. c++ main函数调用 类中的枚举_为啥用枚举,枚举有哪些用法?
  4. 微软图表控件MsChart使用说明[转]
  5. 离散数学及其应用第6版中文版勘误
  6. 小而美的个人博客——前端——tags
  7. PHP锁,分钟级别锁
  8. Ubuntu16.04安装ros残缺包
  9. IDA Plugin 编写基础
  10. Bigraph Extension
  11. tar -zxvf命令_Linux压缩命令小记
  12. Python【第一篇】python安装、pip基本用法、变量、输入输出、流程控制、循环
  13. 你是怎么看待那些拿几千块钱炒股的人?
  14. 【翻译】Brewer's CAP Theorem CAP定理
  15. 中英文对照 —— 计算机编程
  16. 【图像加密】基于matlab混沌算法图像加密解密【含Matlab源码 1218期】
  17. 【转】:localStorage使用总结
  18. Sql Server 2008完全卸载方法(其他版本类似)
  19. 数据库 蚂蚁_蚂蚁金服自研数据库OceanBase性能超过甲骨文引热议
  20. windows server 2012 R2 安装 vc2015 报错 0x80240017

热门文章

  1. Web前端自学之路学习路线,web前端开发网站
  2. Python nan ,ref的含义
  3. CAD高版本窗体阵列LISP_高版本CAD如何显示阵列窗口?
  4. i5-1035G1和i7-1065G7哪个好
  5. 关于 CSS 的英文单词换行 (word-break 和 word-wrap 的区别)
  6. iphone导出照片到pc_如何将照片从iPhone传输到PC
  7. 企业微信-多开 版本4.1.0.6011
  8. mysql学习笔记(六)
  9. js blob转json
  10. 绝地求生2月26服务器维护吗,绝地求生2月26日维护更新内容 绝地求生2月26日更新了什么...