前言
在此之前,我们简单把基础过了一遍,我觉得光讲基础是枯燥且不高效的
于是这节我们来做一个简单的项目,串联之前学过的内容,并且学习一些新的知识
在我个人看来,做项目的特点就一个:抽离
,或者你就记住一个字,抽!
那么抽什么呢?
抽组件,抽数据,抽逻辑,抽所有公共的、多次会用到的东西
你抽的好,那么你的项目就更清晰,后期迭代更高效
记住,我们本文也会围绕抽
来把我们的项目做完,抽完
OK,我们开始吧~
项目结构
在开始之前,我们梳理一下项目结构,这是在基础篇欠给大家的,因为我觉得在实战讲效果会更好
我们新建一个项目,我就叫它project
了

我们目前只需要关注ets
里的内容即可

然后下面我们也只关注resources下base下的media
即可,这里存放我们的静态资源(也就是图片),因为我们这个项目会用到

现在在ets
下有两个文件夹 entryability
和pages

entryability下有个EntryAbility.ts
,这个是我们的程序入口类
,注意,这个是应用层面
的,不是组件层面的,也就是点进我们这个应用会触发的
我们大致看一下里面的内容

大致看一下就行了哈,其中我们看到了里面有很多函数,没错,这是我们应用的生命周期
,不是组件的
里面有很多的hilog.xxx
,这个是应用系统的日志,我们不进行关注

但是其中windowStage.loadContent
指定了我们入口页面
,就是刚进来是哪个页面
在这个入口类当中我们还可以设置一些全局的状态(也可以说是数据),这个状态可以为所有的组件可用,就类似于application
其它的我们目前先不关注
然后我在ets
下新建一个views
来存放我的功能组件
,新建一个model
来存放接口
开始开发

我们看一下我们想要做的效果吧,这里不打算实现所有效果,因为实现所有效果东西不少,需要放的代码也太多了,不打算放在基础篇,这里我们就简单实现一下大致的效果
就这个页面来看有什么
- 首先最下面有一个
导航栏
,分为主页
和记录
- 页面主题部分有很多个小卡片,对应不同的内容,我们第一反应就是这是个公共的组件,我们要给它抽离出来
- 最上面还有一个导航栏,用来切换不同的分类
那么我们开始吧
导航栏
目前有两个导航栏:一个是顶部
的,一个是底部
的 在官方中,已经给了我们Tabs
的组件,我们可以直接用,也给了对应的TabContent
我们先看Tabs
的

首先这两个属性是告诉我们的Tab
你是顶部导航栏,还是底部导航栏
同时它还有一些别的参数

主要是vertical
,它可以控制我们的导航栏是横向的还是纵向的(是否是侧面导航栏)

我们看到SubTabBarStyle
就是我们的顶部菜单,而BottomTabBarStyle
则是底部菜单
同时我们还看到了,顶部菜单只可以有文字
,而底部的则是可以有文字和图标
,这正是我们想要的
我们先来写底部菜单,因为我们要知道,我们底部菜单级别是更大的
,它应该在顶部菜单之上
ts
@Entry
@Component
struct Index {
build() {
Column() {
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Pink)
}.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), '主页'))
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Yellow)
}.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), '记录'))
}
.vertical(false)
.scrollable(true)
.barMode(BarMode.Fixed)
.width('100%')
.backgroundColor(0xF1F3F5)
}
.width('100%')
.height('100%')
}
}
于是我们先得出这样一段代码,我们先来看一下效果

我们已经实现了底部tab栏切换,当然,我们现在先不用管样式
需要注意的是这个图标是Arc给我们的,而其中$r
是引用媒体资源用的,在我们的项目中,我们会引用resources下的内容,就是需要用$r
关于$r
在文档中的位置提供给大家资源限定与访问-框架说明-兼容JS的类Web开发范式-UI开发-开发 | 华为开发者联盟 (huawei.com)
好的,我们已经完成了底部导航栏,那就差顶部的了,这里我们需要注意的是,在我们底部tab上面的内容,都是对应底部tab的TabContent
,这点我们要反应过来
也就是说,我们上面的导航栏要写到底部tab里

也就是这样
然后我们会得到这样的效果

OK,这就是我们想要的效果了,但是我们先不往下写,先把现有的代码优化一下
比如我们的顶部菜单栏的标题是不是不应该写死,它理论上应该是后端传过来的,并且,我们是不是多次使用了TabContent
,我们需要这种多次的类似于列表的操作应该怎么做?
是不是应该配合循环渲染
所以我们现在也改造一下

我们在model
里面来通过class
书写数据
这里注意,最后是需要export
导出,别的组件才可以引入并使用的


效果一样
需要注意的是
TabContent
里只能有一个子组件,所以它里面不能用循环渲染,否则会报错
具体页面
OK,我们现在来写具体的页面内容吧
首先,我们的当前tab下的内容就是一个组件,而这个大的内容下是很多小组件组成

我们先把这个内容组件写上,叫做Home
,再被Index
中调用,然后我想要通过Grid来进行布局,但是我想要Grid循环渲染,所以我先去写它的子组件了


我在views
下新建了一个Item.ets组件
,然后这是它的具体内容

这是它的效果,因为这里基本都是前端基础内容,所以我没有过多叙述
需要注意的是,写完这个子组件之后我们要记得export
导出
好的,现在我们可以在Home组件
中通过Grid
来进行布局Item
组件了
Grid-容器组件-组件参考(基于ArkTS的声明式开发范式)-ArkTS API参考 | 华为开发者联盟 (huawei.com)
这里是Grid布局
的介绍(如果你不会用的话在评论区反馈,我再出一个flex版本),和基本使用,我们需要知道几个属性
columnsTemplate
、columnsGap
、rowsGap

我把作用给大家放在这里
然后我们可以使用了

好的,我们看看效果吧

现在我们只有一条数据,看着不直观,我们多搞几条,首先我们不要把Item组件
的name
写死

然后我们可以在Home
中通过ForEach
进行循环渲染

效果就呈现出来了

结尾
这是我们的第一个小练习,也是项目的最开始
我没有按照官网示例的代码去写,首先,它的确写的很好,但是我觉得大家可能看不懂,所以我写的笨了一些,也进行了一些改动,所以写的不足的地方,欢迎大家指出
当然,这是第一个demo,但不是最后一个demo,因为还有好多知识点没讲呢,而且我们还没抽
完呢
我会尽量循序渐进地带着大家掌握
还有就是,写demo和基础不一样,在写出效果的同时要尽量给大家讲明白,而不是库库放代码,让你cv(这也是大部分代码我都是放的图片原因,我希望大家去手敲),这没意义,所以比较耗时耗力,所以可能更的慢一些,希望大家见谅
文章是在大晚上写的,脑袋可能不够清晰,如果我回头看到了哪里不对会进行更改
当然哪里有误,或者觉得哪里讲的不好听不懂,希望您指出,感谢~
然后我会进行更改的~
大家加油吧