HarmonyOS鸿蒙Next中用十分钟写一个下午茶小投票应用

HarmonyOS鸿蒙Next中用十分钟写一个下午茶小投票应用

每天都在思考今天要吃什么下午茶,不妨看看大家的选择

每天下午困倦的时候,总想点个下午茶慰劳一下忙碌的自己。设计这款app的初衷,就是一个休闲的小投票,汇集大家的选择看看什么是最受欢迎的下午茶。

图片

选择端云一体化开发的理由

在传统开发流程中,分为前端和后端两个部分,前端负责页面展示,后端负责数据处理和逻辑。通常情况下,前端工程师只负责把数据发送给后端,并渲染显示出后端返回的数据。这样的开发逻辑导致前后端开发工程师的技术栈通常不会重叠,而端云一体化开发,似乎给前端工程师带来了更多的机会,让他们可以同时负责页面展示和数据处理。

伟大的道路从创建一个项目开始

创建APPID

登录AGC后台,填写应用名称和包名,然后点击创建

图片

生成证书

由于端云一体化开发不支持自动签名,所以我们需要获取调试证书,在AGC后台上传csr文件生成profile和调试证书,csr证书可以参考官方文档生成

图片

图片

把profile和证书都下载下来

图片

图片

在AGC后台切换到开发与服务选项卡,打开云函数和云数据库功能

图片

新建项目

先创建端云一体项目

注意包名需要和AGC后台保持一致,不然创建项目的时候会提示找不到

图片

图片

图片

云数据库Object配置

在CloudProgram里面找到云数据库,创建一个Object,命名为VoteRecord,并且配置数据列,我这里配置了id、voteId,其中id是自增的,voteId是用户的投票,然后配置索引,我这里配置了一个VoteId索引,权限方面默认就可以了

图片

右键点击VoteRecord,点一下生成DataEntry,这里插入一些预置数据

因为id是自增长的,所以这里直接填voteId就可以了

图片

右键点击VoteRecord,点一下生成Server模型,方便云函数调用云数据库

图片

创建云函数

在CloudProgram里面找到云函数,创建一个云函数,命名为submit-vote,打开函数文件夹下面的package.json,添加云函数调用云数据库的依赖 "@hw-agconnect/cloud-server": "^1.0.2",然后 Sync 一下,不然后续会找不到函数依赖。

图片

图片

添加云函数代码

获取前端传来的VoteId,然后插入到数据库中,最后统计一下数据库中不同的VoteId的数量,返回给前端

import { cloud } from '@hw-agconnect/cloud-server'
import { VoteRecord } from './VoteRecord'

let myHandler = async function(event, context, callback, logger) {
  logger.info(event);

  let body = JSON.parse(event.body || "{}")

  let userVoteId = parseInt(body.voteId || "999") //获取投票ID

  let collection = cloud.database({ zoneName: 'default' }).collection(VoteRecord)

  //校验一下voteId范围在1-4之间
  if (userVoteId >= 1 && userVoteId <= 4) {
    //添加一条记录
    const upsertNum = await collection.upsert({ voteId: userVoteId })
    console.log("upsertNum:" + upsertNum)
  }

  //把人数统计定义出来,分别代表选ABCD的不同人
  let peopleCount = [0, 0, 0, 0]
  for (let i = 0; i < 4; i++) {
    const result = await collection.query().equalTo("voteId", i + 1).countQuery("id")

    //这里官方函数库有点问题,result提示是一个number,但实际上是一个string,必须用ignore指令跳过eslint功能
    //@ts-ignore
    peopleCount[i] = parseInt(result)
  }

  callback(peopleCount)
}

export { myHandler }

部署数据库和云函数,分别在数据库、数据、函数三个地方点击右键进行部署

图片

图片

图片

部署成功后,可以使用官方工具测试函数的返回值

打开DevEco Studio的测试工具

图片

点击测试云函数,可以看到返回一个数字数组代表测试成功

图片

端侧开发

组件界面搭建

这里先做一个简单描述,两组展示选项分别用Column包裹后使用ForEach进行元素循环渲染,在选择框的左侧使用Radio进行单选,右侧使用Text进行文本展示,在结果框架中使用两个Span组成标签,一个显示文本,一个显示投票人数的百分比

Column() {
    Column({ space: 10 }) {
        ForEach(this.foodList, (food: string, index: number) => {
            Row() {
                // 单选框
                Radio({ value: `${index + 1}`, group: 'radioGroup' })
                    .checked(index == 0).onChange((isChecked: boolean) => {
                    // 选择回调
                })
                // 文本标签
                Text(food).margin({ left: 10 })
            }
        })
    }
    .alignItems(HorizontalAlign.Center)
    .width("100%")
    .margin({ top: 50 })

    Button("提交").onClick(async () => {
        // 提交功能
    }).margin({ top: 20 })

    Text("大家这样选:").margin({ top: 20 })

    Column({ space: 15 }) {
        ForEach(this.foodList, (food: string, index: number) => {
            Row() {
                Text() {
                    // 文本标签
                    Span(food)
                    // 百分比标签,这里考虑到分母为0的情况,需要进行判断
                    Span(` ${this.chosenList[index]} (${(this.chosenList.reduce((v, c) => v + c, 0) == 0 ? 0 :
                    Math.round(this.chosenList[index] * 100 / this.chosenList.reduce((v, c) => v + c, 0)))}%)`)
                }
            }
        })
    }
    .alignItems(HorizontalAlign.Center)
    .width("100%")
    .margin({ top: 20 })
}.justifyContent(FlexAlign.SpaceAround)
.alignItems(HorizontalAlign.Center)

数据流开发

本案例只有一个状态变量chosenList,用于存储每个选项的选择人数,同时创建一个包裹函数用于调用云函数,传入参数选择项index,返回一个数组,数组的每个元素代表一个选项的选择人数

其余变量保存用户选择的选项index,用于在选择框的左侧进行单选,然后还有一个文本标签用于渲染选项名称

checkedItem = -1
foodList: string[] = ["咖啡", "奶茶", "汽水", "雪糕"]

@State chosenList: number[] = [0, 0, 0, 0]

async callCloudFunction(index?: number): Promise<number[]> {
    let result = await cloudFunction.call({
        name: 'submit-vote',
        timeout: 10 * 1000,
        data: {
            voteId: index
        }
    })
    console.log("result:" + JSON.stringify(result.result))
    return result.result as number[]
}

页面进入时调用

函数调用方式很简单,把数据流串在一起就可以了,这里需要注意的是,因为是异步调用,所以需要使用await关键字等待函数返回结果,然后再把结果赋值给数据流。这里展示的是onDidBuild生命周期函数,在页面构建完成后调用,这样可以刚进入页面的时候就展示数据

async onDidBuild(): Promise<void> {
    this.chosenList = await this.callCloudFunction()
}

单选按钮调用

单选按钮逻辑很简单,把用户选择的index赋值给checkedItem

this.checkedItem = index + 1

按钮调用

按钮和onDidBuild类似,只是这里要把用户选择的index传进去,然后刷新投票数量,更新到结果里面

Button("提交").onClick(async () => {
    this.chosenList = await this.callCloudFunction(this.checkedItem)
}).margin({ top: 20 })

证书配置和真机调试

这时候我们就可以插上我们的真机进行调试,因为模拟器不支持端云一体,所以我们需要手动配置签名并安装到真机上,配置好后插上真机,点击三角符号运行就可以了

图片

总结

通过这个案例,我们可以看到,端云一体化开发可以让前端工程师同时负责页面展示和数据处理,这样可以提高开发效率,减少开发成本。同时,端云一体化开发也可以让前端工程师更加了解后端的开发流程,这样可以更好地进行开发。

但同时也发现了一些官方手册的问题,比如云函数的返回值类型提示是一个number,但实际上是一个string,这会导致一些问题,比如在使用官方工具测试函数的时候,和实际客户端发送的数据结构压根不一样,而官方文档完全没有提及这个事情,甚至连一个可以跑的范例都没提供。

总体来说,瑕不掩瑜,端云一体化开发确实为开发者节省了不少部署服务器和学习的时间,祝大家都能够掌握这门技术,开发出令人激动的作品。


更多关于HarmonyOS鸿蒙Next中用十分钟写一个下午茶小投票应用的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

所以云函数是可以访问云数据库的是吧?

更多关于HarmonyOS鸿蒙Next中用十分钟写一个下午茶小投票应用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中创建投票应用:

  1. 使用DevEco Studio新建Empty Ability项目
  2. 在entry/src/main/ets/pages/index.ets中编写UI:
@Entry
@Component
struct Index {
  @State options: string[] = ['奶茶','咖啡','果汁']
  @State votes: number[] = [0,0,0]

  build() {
    Column() {
      ForEach(this.options, (item, index) => {
        Button(item + `: ${this.votes[index]}票`)
          .onClick(() => {
            this.votes[index] += 1
          })
      })
    }
  }
}
  1. 运行预览器即可测试投票功能。

这是一个很好的HarmonyOS Next端云一体化开发示例!我来补充几点技术要点:

  1. 云数据库配置很规范,特别是索引和权限设置合理。voteId索引能有效提升查询性能,权限配置也考虑了不同用户角色的操作需求。

  2. 云函数处理逻辑完整:

  • 参数校验确保voteId在有效范围
  • 使用upsert避免重复插入
  • 统计查询使用countQuery优化性能
  1. 前端实现简洁高效:
  • 使用@State管理状态
  • 合理使用ForEach渲染列表
  • 异步调用处理得当
  1. 需要注意的细节:
  • 云函数返回类型问题确实存在,需要类型断言
  • 百分比计算处理了除零情况
  • 真机调试是必须的

这个示例完整展示了从云数据库配置到前端交互的全流程,对学习端云一体化开发很有参考价值。特别是将云函数和前端状态管理结合的部分,体现了HarmonyOS Next的开发特点。

回到顶部