【HarmonyOS】体验鸿蒙电商平台的未来之旅!

           从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?

今天实现一个简单的小案例,从零开始讲解如何通过鸿蒙开发实现一个电商平台的案例。

目录

新建项目

登录页面

点击登录

个人中心

首页搭建

Tabs组件


新建项目

首先我们先打开DevEco Studio,点击新建项目:

然后根据自己的情况选择应用,这里我们选择空的 Empty Ability 进行创建:

然后接下来输入自己的项目名称就行,点击finish即可:

运行本地预览器,可以看到我们的初始项目已经跑通:

登录页面

登录页面的构建很简单,我们参考网上的登录页面,简单的构建一下登录页面的画面,这里我使用的图标都是来自阿里云图标库当中,大家可以根据自己的情况在网上寻找资源来构建画面,闲话少说我们直接开始,首先我们在pages文件夹下新建arkts文件Login文件,当作是我们的登录页面,接下来我们开始正式编写相关代码:

因为构建静态页面很简单,也没有什么好讲的,这里我就将静态页面的源代码直接共享出来吧,大家可以自己看一下:

// 登录页面// 文本框样式
@Extend(TextInput) function InputStyle() {.placeholderColor('#ff5d7e9d').height(60).fontSize(20).backgroundColor('#ccc').width('90%').padding({ left: 15 }).maxLength(10)
}// 分割线
@Extend(Line) function liseStyle() {.width('100%').height(2).backgroundColor('#efefef').margin({ top: 10, bottom: 10 })
}// Text组件的蓝色文本样式
@Extend(Text) function blueTextStyle() {.fontColor('#ff084d85').fontSize(15).fontWeight(FontWeight.Bold)
}@Entry
@Component
struct Login {@State account: string = '' // 登录账号@State password: string = '' // 登录密码@State isShowProgress: boolean = true // 是否显示登录的进度条// 构建登录按钮@Builder imageButton(image: Resource) {// 构建按钮图片,本质上就是在按钮里面增加一个image组件Button({ type: ButtonType.Circle, stateEffect: true }){ // 圆形按钮,按下按钮有切换颜色效果Image(image)}.height(50).width(50).backgroundColor('#fff')}build() {Column() { // 登录界面的布局Image($r('app.media.login_logo')) // Logo图片.width($r('app.float.logo_image_size')).height($r('app.float.logo_image_size')).margin({top: $r('app.float.logo_margin_top'),bottom: $r('app.float.logo_margin_bottom')})// 登录标题Text($r('app.string.login_page')).fontSize($r('app.float.page_title_text_size')).fontWeight(FontWeight.Medium).fontColor($r('app.color.page_title_text_color'))// 小标题Text('登录账号以获取更多服务').fontSize(20).fontColor('#ccc').margin({ top: 15, bottom: 25 })// 账号输入框TextInput({ placeholder: '请输入账号' }).InputStyle().type(InputType.Number) // 文本行中只能输入数字.onChange((value: string) => {this.account = value})Line().liseStyle()// 密码输入框TextInput({ placeholder: '请输入密码' }).InputStyle().type(InputType.Password).onChange((value: string) => {this.password = value})Line().liseStyle()// 短信提示与验证码Row(){Text('短信验证码登录').blueTextStyle()Text('忘记密码').blueTextStyle()}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({ left: 12, right: 12 })// 登录按钮Button('登录', { type: ButtonType.Capsule }).width('75%').height(45).fontSize(20).fontWeight(FontWeight.Bold).margin({ top: 60, bottom: 20 }).onClick(() => {// 登录事件})// 注册账号文本Text('注册账号').fontColor('blue').fontSize(15).fontWeight(FontWeight.Medium)// 是否显示进度条if (this.isShowProgress){LoadingProgress().color('red').width(40).height(40).margin({ top: 10 })}// 其他方式登录Text('其他方式登录').fontColor('#ff776f6f').fontSize(18).fontWeight(FontWeight.Medium).margin({ top: 5, bottom: 10 })// 三种登录方式Row({ space: 40 }){this.imageButton($r("app.media.wx"))this.imageButton($r("app.media.tb"))this.imageButton($r('app.media.qq'))}}.width('100%').height('100%')}
}

最终呈现的效果如下:

关于这个静态页面的构建我简单提一下,对于公共常用的样式,我们可以将其书写在静态资源base当中然后进行调用即可,上文的代码我进行了简单的使用,主要的方式如下:

点击登录

接下来我们给我们静态页面的登录按钮设置点击事件进行登录操作,以及对进度条的显示进行一个设置,当点击登录和进入到正式页面之间的间隔中进行显示这个进度条出来,闲话少说正式开始:

@State isShowProgress: boolean = false // 是否显示登录的进度条
private timeOutId: number = -1 // 控制登录超时的时间变量// 登录回调事件
Login(): void {if(this.account === '' || this.password === ''){promptAction.showToast({ // 开启一个确认弹层message: '账号密码为空,请重新输入!'})} else {this.isShowProgress = trueif(this.timeOutId == -1) {this.timeOutId = setTimeout(() => {// 2秒之后执行的函数this.isShowProgress = falsethis.timeOutId = -1// 页面跳转}, 2000)}}
}

然后我们在离开页面的时候,对定时器进行一个清除:

// 离开页面要取消定时器
aboutToDisappear() {clearTimeout(this.timeOutId)this.timeOutId = -1
}

实现的效果如下:

接下来我们开始实现点击登录按钮后,触发点击事件进行页面的路由跳转,代码如下,关于个人中心页面的搭建,可以继续看下一个标题的内容:

个人中心

接下来开始实现个人中心的页面,个人中心的页面搭建其实也非常简单,这里我们把要存放的图片和相关标题的内容单独抽离出去,形成一个新的类,来获取静态资源,后面需求页面要使用的时候直接调用就可以了,具体代码如下:

interface ItemData {title: string;imagePath: Resource;switch?: boolean;
}export class DataModel {// 获取列表数据getSettingListData(): ItemData[] {let settingListData: ItemData[] = [{title: '推送通知',imagePath: $r('app.media.1'),switch: true,},{title: '数据管理',imagePath: $r('app.media.2'),switch: false,},{title: '菜单设置',imagePath: $r('app.media.3'),switch: false,},{title: '关于个人',imagePath: $r('app.media.4'),switch: false,},{title: '清除缓存',imagePath: $r('app.media.5'),switch: false,},{title: '隐私协议',imagePath: $r('app.media.6'),switch: false,},];return settingListData;}
}export default new DataModel();

关于这些静态资源的图片可以到阿里云图标库上寻找,这里就不再赘述了:

然后接下来我们需要开始正式的书写我们的个人中心页面的代码了,具体静态页面代码如下:

import router from '@ohos.router'
import DataModel from '../../components/DataModel'
import promptAction from '@ohos.promptAction'// 设置界面
@Entry
@Component
struct MySettings {@State account: number = 0onPageShow(){let acc = router.getParams() as Record<string, number>if (acc) {this.account = acc['sendMsg']}}// 构建设置单元格函数@Builder settingCell(item) {Row(){Row({ space: 10 }) {Image(item.imagePath).width(38).height(38)Text(item.title).fontSize(25)}// 判断switch是否为trueif(!item.switch) {Image($r('app.media.arrow_right')).width(30).height(30)} else {Toggle({ type: ToggleType.Switch, isOn: false }) // 显示一个开关组件}}.justifyContent(FlexAlign.SpaceBetween).width('100%').padding({ left: 15, right: 15 })}build() {Scroll(){Column({ space: 12 }){Column(){ // 创建一个内嵌的列布局Text('个人中心').fontWeight(FontWeight.Bold).fontSize(40).margin({ top: 10 }).padding({ left: 15 })}.width('100%').alignItems(HorizontalAlign.Start)// 账户布局Row(){Image($r('app.media.account')).width(60).height(60)Column(){Text('张三').fontSize(25)Text(`${this.account.toString()}@163.com`).fontSize(15).margin({ top: 8 })}.layoutWeight(2).alignItems(HorizontalAlign.Start).margin({ left: 30 })}.width('100%').height(70).backgroundColor(Color.White).padding({ left: 20, right: 20 }).borderRadius(20).margin({ top: 30 }).alignItems(VerticalAlign.Center)// 列表布局List(){ForEach(DataModel.getSettingListData(), (item, index) => {ListItem(){this.settingCell(item)}.onClick(() => {promptAction.showDialog({message: `第${index + 1}功能:${item.title},还未完成,尽情期待!`})}).height(60)})}.backgroundColor(Color.White).width('100%').divider({strokeWidth: 1, // 设置分割线的高度color: Color.Gray, // 设置分割线的颜色startMargin: 15, // 设分割线的起始边距endMargin: 15 // 设置分割线的结束边距}).borderRadius(30).padding({ top: 15, bottom: 20 })Blank()// 退出按钮的布局Button('退出登录', { type: ButtonType.Capsule }).width('90%').height(50).fontSize(20).fontColor('red').backgroundColor('#ccc').margin({ bottom: 15 })}.height('100%')}.width('100%').height('100%')}
}

呈现的效果如下所示:

然后接下来我们给退出登录的按钮设置点击事件:

首页搭建

接下来开始实现首页的页面搭建,静态页面的搭建其实很简单,博主也没有什么好讲的说实话,无非就是Grid布局以及Swiper布局的排版一下注意一点就可以了,ok接下来我们开始给出具体代码吧:

import DataModel from '../../components/DataModel'// 首页
@Entry
@Component
struct Home {private swiperController: SwiperController = new SwiperController() // 轮播控制器实例build() {Scroll(){Column({ space: 10 }){Column(){ // 标题Text('首页').fontWeight(FontWeight.Bold).fontSize(30).margin({ top: 10 }).padding({ left: 10 })}.width('100%').alignItems(HorizontalAlign.Start)// 轮播图片Swiper(this.swiperController){ForEach(DataModel.getSwiperImage(), (item) => {// 构建每一张图片Image(item.imagePath).width('100%').height(250).borderRadius(50)})}.autoPlay(true) // 轮播图自动播放.margin({ top: 15 })// 菜单列表Grid(){ForEach(DataModel.getFirstGridData(), (item) => {GridItem(){Column(){Image(item.imagePath).width(40).height(40)Text(item.title).fontSize(15).margin({ top: 5 })}}})}.columnsTemplate('1fr 1fr 1fr 1fr') // 设置网格的列模板,每列平分空间.rowsTemplate('1fr 1fr') // 设置网格的行模板,每行平分空间.columnsGap(10).rowsGap(10).padding({ top: 10, bottom: 10 }).height(200).backgroundColor(Color.White).borderRadius(50)// 频道列表Text('列表').fontSize(20).fontWeight(FontWeight.Bold).width('100%').margin({ top: 15 })Grid(){ForEach(DataModel.getSecondGridData(), (item) => {GridItem() {Column() {Text(item.title).fontSize(20).fontWeight(FontWeight.Medium)Text(item.describe).fontSize(15).fontColor('#ccc').margin({ top: 5 })}.alignItems(HorizontalAlign.Start) // 两个文本框在水平方向居左对齐}.padding({ top: 15, left: 10 }).borderRadius(10).align(Alignment.TopStart) // 设置网格项对齐方式为顶部对齐.backgroundImage(item.imagePath) // 设置网格项背景图像.backgroundImageSize(ImageSize.Cover) // 设置背景图像尺寸模式为覆盖.width('100%').height('100%')})}.width('100%').height(300).columnsTemplate('1fr 1fr').rowsTemplate('1fr 1fr') // 设置网格的行列模板.columnsGap(10).rowsGap(10).margin({ bottom: 15 })}}.height('100%')}
}

最终呈现的效果如下:

Tabs组件

ArkUI开发框架提供了一种页签容器标签Tabs,开发者通过Tabs组件可以很容易的实现内容视图的切换。页签容器 Tabs 的形式多种多样,不同的页面设计页签不一样,可以把页签设置在底部、顶部或者侧边。

接下来我们创建页面组件index,然后在页面组件当中书写tab页面:

import Home from './Home'
import MySettings from './MySettings'
import router from '@ohos.router'// app主页,页面组件
@Entry
@Component
struct Index {@State currentIndex: number = 0 // 当前默认的页签索引号private account: numberprivate tabsController: TabsController = new TabsController()// 接收路由参数onPageShow(){let acc = router.getParams() as Record<string, number>if (acc) {this.account = acc['sendMsg']}}// 自定义Tabs函数@Builder TabBuilder(title: string, index: number, selectedImg: Resource, normalImg: Resource) {Column() {Image(this.currentIndex == index ? selectedImg : normalImg).width(30).height(30)Text(title).margin({ top: 5 }).fontSize(15).fontColor(this.currentIndex == index ? '#008c8c' : '#ccc')}.justifyContent(FlexAlign.Center).width('100%').height('50').onClick(() => {this.currentIndex = indexthis.tabsController.changeIndex(this.currentIndex) // 修改页签的索引})}build() {Tabs({barPosition: BarPosition.End, // 页签底部展示controller: this.tabsController // 页签容器的控制}){ // 标签容器// 首页TabContent(){Home()}.padding({ left: 20, right: 20 }).backgroundColor('#ccc').tabBar(this.TabBuilder('首页', 0, $r('app.media.home_active'), $r('app.media.home')))// 个人中心TabContent(){MySettings({ account: this.account })}.padding({ left: 20, right: 20 }).backgroundColor('#ccc').tabBar(this.TabBuilder('我的', 1, $r('app.media.my_active'), $r('app.media.my')))}.animationDuration(0) // 去掉切换页面的动画效果.scrollable(false) // 去掉滑动效果,只能点击按钮切换界面.width('100%').backgroundColor(Color.White).barHeight(50).barMode(BarMode.Fixed)}
}

这里我们需要将之前的Home页面以及MySettings页面进行一个暴露出去:

这里简单提一下,当用户点击登录按钮之后,这里我们需要跳转到index页面的,所以携带的路由参数也是先传递给index页面,然后index页面再传递给子组件MySettings组件当中,这里注意一下:

最终呈现的效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/243161.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【堂堂狼人杀(定制开发)】

堂堂狼人杀游戏♨️风险规避与优势。?零投资也可参与规避五大风险 政策风险(点对点场外交易)账户风险(无资金池&#xff09; 推广风险(免费注册&#xff0c;注册送大礼包&#xff09; 网络风险(大平台&#xff0c;全网场外交易) 人脉风险(预约角色&#xff0c;强制出售) …

力扣hot100 相交链表 超全注释 满级表达

Problem: 160. 相交链表 文章目录 思路复杂度&#x1f496; Ac Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 &#x1f469;‍&#x1f3eb; 参考图解 复杂度 时间复杂度: O ( n m ) O(nm) O(nm) 空间复杂度: 添加空间复杂度, 示例&#xff1a; O ( 1 ) O(1) O(…

python 正则表达式学习(1)

正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。 1. 特殊符号 1.1 符号含义 模式描述^匹配字符串的开头$匹配字符串的末尾.匹配任意字符&#xff0c;除了换行符&#xff0c;当re.DOTALL标记被指定时&#xff0c;则可以匹配包…

飞书+ChatGPT+cpolar搭建企业智能AI助手并实现无公网ip远程访问

文章目录 推荐 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂…

用pandas实现用前一行的excel的值填充后一行

今天接到一份数据需要分析&#xff0c;数据在一个excel文件里&#xff0c;内容大概形式如下&#xff1a; 后面空的格子里的值就是默认是前面的非空的值&#xff0c;由于数据分析的需要需要对重复的数据进行去重&#xff0c;去重就需要把控的cell的值补上&#xff0c;然后根据几…

数字IC后端设计实现 | PR工具中到底应该如何控制density和congestion?(ICC2Innovus)

吾爱IC社区星友提问&#xff1a;请教星主和各位大佬&#xff0c;对于一个模块如果不加干预工具会让inst挤成一团&#xff0c;后面eco修时序就没有空间了。如果全都加instPadding会导致面积不够overlap&#xff0c;大家一般怎么处理这种问题&#xff1f; 在数字IC后端设计实现中…

Python内置的20个高阶函数的功能和示例详解

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python是一门功能丰富的编程语言&#xff0c;提供了许多内置函数来处理各种数据操作。其中&#xff0c;高阶函数是一类特殊的函数&#xff0c;它们接受其他函数作为参数&#xff0c;或者返回函数作为结果。高阶函…

如何禁用WordPress站点的管理员电子邮件验证或修改检查频率?

今天boke112百科登录某个WordPress站点时&#xff0c;又出现“管理员邮件确认”的提示&#xff0c;要求确认此站点的管理员电子邮箱地址是否仍然正确。具体如下图所示&#xff1a; 如果点击“稍后提醒我”&#xff0c;那么管理员邮件验证页面就会在3天后重新显示。 说实话&…

Unity - 简单音频

“Test_04” AudioTest public class AudioTest : MonoBehaviour {// 声明音频// AudioClippublic AudioClip music;public AudioClip se;// 声明播放器组件private AudioSource player;void Start(){// 获取播放器组件player GetComponent<AudioSource>();// 赋值…

搭建开源数据库中间件MyCat2-配置mysql数据库双主双从

mycat2官网&#xff1a;MyCat2 前言&#xff1a;mycat2下载地址无法访问&#xff0c;不知道是不是被DNS污染了&#xff0c;还是需要搭梯子访问&#xff0c;所以我只能找到1.21的版本进行安装。搭建mycat2的前提是搭建数据库主从复制。 架构&#xff1a;双主双从 配置&#xf…

Verilog基础:强度建模与net型信号的多驱动问题(三)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 四、一般情况下的net型信号的线与组合&#xff08;线网多驱动&#xff09; 在Verilog基础&#xff1a;强度建模与net型信号的多驱动问题&#xff08;二&#xff0…

成功解决java.nio.charset.MalformedInputException: Input length = 1

项目启动时报错如下 Connected to the target VM, address: 127.0.0.1:5309, transport: socket 18:01:22.607 [main] ERROR o.s.b.SpringApplication - [reportFailure,843] - Application run failed org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedIn…

开年大瓜!Mobileye股价暴跌

编者按&#xff1a;作为汽车智能化的第一波受益者&#xff0c;Mobileye的市场红利已经接近尾声。尤其是汽车芯片市场的白热化竞争&#xff0c;新一轮格局重构正在开启。 汽车智能化的供给关系&#xff0c;正在发生微妙变化。 本周&#xff0c;作为全球主要的辅助驾驶芯片及感知…

Joern环境的安装(Windows版)

Joern环境的安装(Windows版) 网上很少有关于Windows下安装Joern的教程&#xff0c;而我最初使用也是装在Ubuntu虚拟机中&#xff0c;这样使用很占内存&#xff0c;影响体验感。在Windows下使用源码安装Joern也是非常简单的过程&#xff1a; 提前需要的本地环境&#xff1a; …

【大数据】流处理基础概念(一):Dataflow 编程基础、并行流处理

流处理基础概念&#xff08;一&#xff09;&#xff1a;Dataflow 编程基础、并行流处理 1.Dataflow 编程基础1.1 Dataflow 图1.2 数据并行和任务并行1.3 数据交换策略 2.并行流处理2.1 延迟与吞吐2.1.1 延迟2.1.2 吞吐2.1.3 延迟与吞吐 2.2 数据流上的操作2.2.1 数据接入和数据…

GPS位置虚拟软件 AnyGo mac激活版

AnyGo for Mac是一款一键将iPhone的GPS位置更改为任何位置的强大软件&#xff01;使用AnyGo在其iOS或Android设备上改变其GPS位置&#xff0c;并在任何想要的地方显示自己的位置。这对那些需要测试应用程序、游戏或其他依赖于地理位置信息的应用程序的开发人员来说非常有用&…

【网络奇遇记】揭秘计算机网络性能指标:全面指南

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 速率1.1 数据量1.2 速率 二. 带宽三. 吞吐量四. 时延4.1 发送时延4.2 传播时延…

苹果电脑(Mac)的node版本安装以及升降级

在开发过程中&#xff0c;对于不同的开发环境或者较老的项目可能需要切换不同的node版本&#xff0c;此过程会涉及到node版本的升级与降级&#xff0c;安装node版本管理模块n&#xff08;sudo命令&#xff09;。 全局安装n模块 sudo npm install n -g//输入后回车&#xff0c…

MarkDown学习笔记 直观全面详细

前言 为什么我们要学习Markdown呢&#xff1f;因为Markdown简单易学易上手&#xff0c;可以以纯文本格式编写文档&#xff0c;然后转换成有效的HTML文档&#xff0c;并且以导出 HTML 、Word、图像、PDF、Epub 等多种格式的文档&#xff0c;许多网站平台的文章、博客、论文均可…

8.3 Springboot整合Redis 之Jedis方式

文章目录 前言一、Maven依赖二、新增子Module:tg-book-redis三、Jedis配置类3.1 Jedis连接池核心配置说明四、Jedis 工具类五、新增controller测试前言 Jedis是Redis官方推荐的Java客户端连接工具,用法非常简单,Jedis的API与Redis的API可以说是一模一样,所以非常有利于熟悉…