本篇文章我来手把手教大家做一个HarmonyOS 应用的登录页面,逐步讲解,非常细致,百分百能学会,并提供全部源码。页面使用 DevEco Studio 的低代码开发。
通过本文的实践经验,我想告诉大家, HarmonyOS 应用开发其实并不难,只要了解具体的开发流程和开发思想,大家都可以很快上手。祝愿大家都可以赶上时代浪潮,让青春随鸿蒙千帆飘扬!

下面这张图是我们的目标实现图,具体实现流程将由我一步一步讲解:

一、项目初始化

1、创建低代码项目

下载安装 DevEco Studio,新建一个支持 Super Visual 低代码模式的项目。

具体过程可以参考我上一篇文章:HarmonyOS应用开发-搭建开发环境


2、低代码项目结构解读

初始项目目录如下:

├──entry/src/main/ets           // 代码区
│  ├──entryability              
│  │  └──EntryAbility.ets       // 程序入口类
│  └──pages
│     └──Index.ets              // 首页的逻辑描述文件
├──entry/src/main/resources     // 资源文件
└──entry/src/main/supervisual└──pages└──Index.visual           // 首页的数据模型

其中.ets文件就是我们正常编写界面逻辑的文件,语言为ArcTS;
.visual为低代码项目特有的文件,由系统根据我们对界面的可视化设计自动更新,用写字板打开能看到是存储界面设计的Json文本;


二、添加静态文件

1、新增图片文件

ets 文件下创建 common\images\icon 文件夹,icon内添加我们需要添加的图片文件,本教程我们用到了3个“其他登录方式”的图标。

添加的图标图片如下:

增加完三个图标后,我们的项目结构更新如下:

├──entry/src/main/ets           // 代码区
│  ├──common                    
│  │  └──images                 
│  │     └──icon                // 图标图片
│  │        ├──csdn.png         // 图标A
│  │        ├──huawei.png       // 图标B
│  │        └──openatom.png     // 图标C
│  ├──entryability              
│  │  └──EntryAbility.ets       // 程序入口类
│  └──pages
│     └──Index.ets              // 首页的逻辑描述文件
├──entry/src/main/resources     // 资源文件
└──entry/src/main/supervisual└──pages└──Index.visual           // 首页的数据模型


2、新增常量类

这一步可选,一般意义上,我们会根据系统业务需要把一些固定的参数写到一个记录常量的 ArcTS 文件里,比如命名为 Const.ts,本次我们把页面需要的常量写到了页面自带的 index.ets文件里,所以没有建立常量类,特此说明。

如果需要添加,我们可以把常量类 Const.ts 放在和 images 文件夹平级的位置,添加 Const.ts 之后的项目结构如下:

├──entry/src/main/ets           // 代码区
│  ├──common                    
│  │  ├──Const.ts               // 常量类
│  │  └──images                 
│  │     └──icon                // 图标图片
│  │        ├──csdn.png         // 图标A
│  │        ├──huawei.png       // 图标B
│  │        └──openatom.png     // 图标C│  ├──entryability              
│  │  └──EntryAbility.ets       // 程序入口类
│  └──pages
│     └──Index.ets              // 首页的逻辑描述文件
├──entry/src/main/resources     // 资源文件
└──entry/src/main/supervisual└──pages└──Index.visual           // 首页的数据模型

三、编写登录页界面

1、低代码设计界面布局

① 放置容器组件

初始话的页面如图,Root 根结构下包含一个 Column 的容器,容器里有一个 "Hello World" 的 Text 文本控件。

我们直接复用这个 Column 容器,删除 Text 控件(左侧组件树或右侧可视化屏幕里选中控件然后按Backspace键就可以删除)。


② 放置图标图片

如图,我们需要放置一个水平居中的应用图标:

思路:下面我们来实现登录页面的图标,我们需要创建一个行容器(Row),然后拖一个图片组件(Imgae)进去,并使图片居中。

操作:在列容器(Cloumn)里拖一个行容器(Row)过去,宽度(width)设置为 100%,高度(height)设置为 100vp,设置水平居中、垂直居中,位置为绝对定位(Position),距离页面上方 95vp 距离。

然后我们拖入图片组件(Imgae),设置图片宽高均为 100vp(和Row的高相等)。

图片的Src(图片存储路径)设置为app自带的默认图标,至此我们的登录页应用图标就显示出来了。


③ 放置描述文字

接下来,我们需要放置描述性文本,如图:

思路:这里用到的是文本组件(Text),我们需要填写文字内容、定义字体大小和组件的位置。

操作:拖两个文本组件(Text)到行容器(Row)下面。

设置内容(Content)为 "用户登录",字体大小(FontSize)为 26fp,字体对齐(TextAlign)为居中(Center),文字组件框体大小(Size)为宽度 100%,高度 50vp,位置为绝对定位(Position),距离页面顶部 200vp。效果图如下:

同理,我们制作 "登录账号以使用更多服务" 文本框。

我们设置文本框内容(Content)为 "登录账号以使用更多服务",字体大小(FontSize)为 14fp,字体对齐(TextAlign)为居中(Center),文字组件框体大小(Size)为宽度 100%,高度 30vp,位置为绝对定位(Position),距离页面顶部 250vp,字体颜色(FontColor)为 #8c8c8c(灰色)。效果图如下:


④ 放置账号密码输入框

接下来,我们要制作账号密码的输入部分,这里用到的是文本输入组件(TextInput)。
目标实现效果如下:

思路:我们需要两个文本输入组件(TextInput)用来实现账号、密码的录入,下方 "短信验证码登录" 和 "忘记密码",我们使用普通文本组件(Text)实现,让两个普通文本组件(Text)并列在一行,然后一个左对齐,一个右对齐。

操作流程:

首先,我们处理账号和密码输入两个文本输入框。

拖两个文本输入组件(TextInput)在我们之前拖的组件下面。

设置文本输入组件一(text-input1):

设置文本占位符(Placeholder)为 "邮箱/手机号/用户名",类型(Type)为 Normal;
组件框体大小(Size)为宽度(Width)为 100%,高度(Height)为 50vp;
背景颜色(BackgroundColor)为白色(#ffffff);
边框(Border)只要底边框,底边框宽度(BorderBottomWidth)为 1vp,边框颜色(BorderColor)为深灰色(#4a4a4a);
位置为绝对定位(Position),距离页面顶部 328vp。

效果图如下:

设置文本输入组件二(text-input2):

设置文本占位符(Placeholder)为 "邮箱/手机号/用户名",类型(Type)为 Password;
组件框体大小(Size)为宽度(Width)为 100%,高度(Height)为 50vp;
背景颜色(BackgroundColor)为白色(#ffffff);
边框(Border)只要底边框,底边框宽度(BorderBottomWidth)为 1vp,边框颜色(BorderColor)为深灰色(#4a4a4a);
位置为绝对定位(Position),距离页面顶部 380vp。

效果图如下:

下一步,我们来制作两个输入框下面的 "短信验证码登录" 和 "忘记密码"。

拖一个行容器(Row)到文本输入框组件下面,设置行容器(Row)的属性。
设置组件居中;
设置组件的尺寸(Size),宽度(Width)为 94%,高度(Height)为 30vp;
设置组件位置为绝对定位(Position),距离页面顶部 430vp,距离左侧为 3%;

接着,我们往容器里拖两个文本组件(Text)。

设置组件属性如下:
组件一(text5)内容为 "短信验证码登录",字体居左,字体大小为 14fp;
定义尺寸(Size),宽度(Width)为 50%,高度(Height)为 30vp;
组件位置为绝对定位(Position),距离左侧为 0%;

组件二(text6)内容为 "忘记密码",字体居右,字体大小为 14fp;
定义尺寸(Size),宽度(Width)为 50%,高度(Height)为 30vp;
组件位置为绝对定位(Position),距离左侧为 50%;


⑤ 放置登录按钮

这一步是最简单的,制作登录按钮部分,只需要一个按钮组件(Button)和一个文本组件(Text)。
目标实现效果如下:

思路:我们拖一个按钮组件(Button),再在按钮下方拖一个文本组件(Text)即可。

操作流程:

首先,我们拖一个按钮组件。

定义组件的属性:
设置组件宽度(Width)为 90%,高度(Height)为 40vp;
内容为"登录",字体默认居中,字体大小为 20fp;
组件位置为绝对定位(Position),距离左侧为 5%,距离顶部 530vp;

下方再拖一个文本组件(Text),设置组件属性:
文本组件内容为 "注册账号",字体居中,字体大小为 14fp;
定义尺寸(Size),宽度(Width)为 100%,高度(Height)为 30vp;
组件位置为绝对定位(Position),距离顶部为 570vp;


⑥ 放置Grid网格控件

最后,我们来制作其他登录方式的选择部分,这里用到的是网格组件(Grid)、网格内单个元素(GridItem)、其他常见组件(图片、文字、行/列等)。
目标实现效果如下:

思路:我们需要一个网格组件(Grid),组件内包含若干个子元素,这个用Grid内对象组件(GridItem)可以实现,这样我们就可以根据我们后端传值的数目来动态显示登录方式,而不是把三种登录方式固定写死。每个Grid内子元素(GridItem)里放置一个行容器(Row),行容器(Row)里上方放一个图片组件(Image),下方放一个文本组件(Text)。

操作流程:

首先,我们拖一个网格组件(Grid),设置组件属性:
组件宽度(width)设置为 100%,高度(height)设置为 10%;
内容居中,绝对定位,距离顶部 90%;

往网格组件(Guid)里拖一个GuidItem组件,这是一个动态显示的子元素组件,会根据我们提供的参数动态进行内容显示,由于我们在设计上固定为行内显示3个,所以宽度就直接定为33.3%了。

设置GridItem组件属性:
组件宽度(width)设置为 33.3%,高度(height)设置为 100%(因为是相对于Grid);

往GridItem里拖入一个行容器(Row),设置组件属性:
高度和宽度均为 100%;

然后再往行容器(Row)里拖一个图片组件(Image)和一个文本组件(Text);

设置组件属性:

图片(Image)组件:
图片路径(Src),我们使用编译器自带的 Logo;
对象适应方式(ObjectFit) 为包含(Contain);
组件宽度(width)设置为 70%,高度(height)设置为 56%;
距离上边距(MarginTop) 10%;
绝对定位,距离左侧 15%;

文字(Text)组件:
文字内容(Content),我们先随便填个 "测试";
文本居中;
组件宽度(width)设置为 100%,高度(height)设置为 24%;
绝对定位,距离顶部 60%(60%~70%均可);

做到这里,我们的ArcUI的设计就完成了,是不是觉得和下面三个图标的目标效果还有点差距,别急,我们接下来就来实现GridItem数据的动态渲染。


2、实现数据动态渲染

下一步,我们来实现数据的动态渲染,在这个登录页面,我们需要对GridItem组件及其内部组件的属性进行动态赋值。

① 创建数据源

我们先创建数据源,打开页面对应的 ArcTS 文件(比如你现在编辑的可视化低代码界面是Index.visual,那么对应的 ArcTS 文件就是 Index.ets)

默认的页面 .ets 文件内容如下:

@Entry
@Component
struct Index {@State message: string = 'Hello World'build() {}
}

我们在这里创建 FunctionType 对象,用来装配我们需要显示的图片路径和文字内容。

然后再定义状态变量 avenues,数组类型,用来包含我们装配图片路径和文字内容的 FunctionType 对象。

更新后的代码如下:

class FunctionType {name: string;icon: string;
}@Entry
@Component
struct Index {@State avenues: Array<FunctionType> = [{name: 'HuaWei', icon: "common/images/icon/huawei.png"},{name: 'CSDN', icon: "common/images/icon/csdn.png"},{name: 'OpenAtom', icon: "common/images/icon/openatom.png"}]build() {}
}

② 更新动态渲染组件属性

回到我们低代码页面 Index.visual,修改网格子元素组件(GridItem)的Render里的ForEach属性为this.avenues,其他默认;

然后我们再分别选中GridItem里的图片组件和文本组件,对其勾选动态值。

图片组件(Image)的图片路径(Src)选择 item1.icon;

文本组件(Text)的内容(Content)选择 item1.name;

然后我们到预览器(Preview)的窗口里就可以看到已经完成的效果了。

至此,我们的低代码开发部分已全部完成! 


3、低代码页面转为ArcTs文件

这步是可选步骤,根据实际需要决定是否要转,低代码和 ArcTs 在开发页面上各有优势。低代码开发迅速、改动简单,ArcTS 则更方便自定义一些事件,拥有更好的扩展性。一般对于涉及交互业务的页面,页面的功能会相对比较复杂,推荐使用 ArcTS,如果是登录页这种简单业务逻辑页面,可以保留低代码版本,不必转化为 ArcTS 版本。

如果有需要将 .visual 页面转换为 .ets 文件,我们可以点击右上角的转换按钮。

此操作能够将低代码界面转换为 ArcTS 的代码。
注意:转换完之后原有的 .visual 文件会被删除!这个过程不可逆!
目前编译器点击转换按钮后会有 ArcTS 的预览代码,需要点击 Convert 来确认此次操作,本次界面转换结果的预览代码如下:

Index.ets

class FunctionType {name: string;icon: string;
}@Entry
@Component
struct Index {@State avenues: Array<FunctionType> = [{name: 'HuaWei', icon: "common/images/icon/huawei.png"},{name: 'CSDN', icon: "common/images/icon/csdn.png"},{name: 'OpenAtom', icon: "common/images/icon/openatom.png"}]build() {Column() {Column() {Row() {Image($r('app.media.icon')).width("100vp").height("100vp").align(Alignment.Center).offset({ x: "0%", y: "0vp" }).backgroundImageSize(ImageSize.Auto)}        .width("100%").height("100vp").position({ x: "0", y: "95vp" }).displayPriority(0).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)Text("用户登录").width("100%").height("50vp").position({ x: "0vp", y: "200vp" }).borderRadius({ topRight: "0vp" }).textAlign(TextAlign.Center).textOverflow({ overflow: TextOverflow.Clip }).fontSize("26fp").fontWeight(FontWeight.Medium).fontFamily("sans-serif")Text("登录帐号以使用更多服务").width("100%").height("30vp").position({ x: "0vp", y: "250vp" }).fontColor("#8c8c8c").textAlign(TextAlign.Center).fontSize("14fp")TextInput({ placeholder: "邮箱/手机号/用户名" }).width("100%").height("50vp").position({ x: "0vp", y: "328vp" }).borderWidth({ bottom: "1vp" }).borderColor({ bottom: "#4a4a4a" }).backgroundColor("#ffffff").margin({ bottom: "0vp" }).padding({ top: "0vp" }).type(InputType.Normal)TextInput({ placeholder: "密码" }).width("100%").height("50vp").position({ x: "0vp", y: "380vp" }).borderWidth({ bottom: "1vp" }).borderColor({ bottom: "#4a4a4a" }).backgroundColor("#ffffff").type(InputType.Password)Row() {Text("忘记密码").width("50%").height("30vp").position({ x: "50%", y: "0px" }).textAlign(TextAlign.End).fontSize("14fp")Text("短信验证码登录").width("50%").height("30vp").position({ x: "0%", y: "0vp" }).textAlign(TextAlign.Start).fontSize("14fp")}        .width("94%").height("30vp").position({ x: "3%", y: "430vp" })Grid() {if (true) {ForEach(this.avenues,(item1: any, idx1: number) => {GridItem() {Row() {if (true) {Text(`${item1.name}`).width("100%").height("24%").position({ x: "0%", y: "60%" }).textAlign(TextAlign.Center).fontSize("14fp")                }Image($r('app.media.icon')).width("70%").height("56%").position({ x: "15%", y: "0vp" }).margin({ top: "10%", bottom: "0vp", left: "0%", right: "0%" }).objectFit(ImageFit.Contain)}              .width("100%").height("100%")}            .width("33.3%").height("100%").align(Alignment.Start).offset({ x: "0vp", y: "0" })})          }}        .width("100%").height("10%").align(Alignment.Center).position({ x: "0vp", y: "90%" }).backgroundImageSize(ImageSize.Auto).opacity(0.99).margin({ top: "0vp", bottom: "0vp", left: "0vp", right: "0vp" }).padding({ top: "0vp", bottom: "0vp" }).scrollBar(BarState.Off)Button("登录").width("90%").height("40vp").position({ x: "5%", y: "530vp" }).fontSize("20fp")Text("注册账号").width("100%").height("30vp").position({ x: "0vp", y: "570vp" }).textAlign(TextAlign.Center).fontSize("14fp")Text("其他方式登录").width("100%").height("4%").align(Alignment.Center).position({ x: "0vp", y: "85%" }).textAlign(TextAlign.Center).fontSize("14fp")}      .width("100%").height("100%").position({ x: "0vp", y: "0vp" }).borderWidth({ bottom: "1vp" }).borderColor({ bottom: "#4a4a4a" }).justifyContent(FlexAlign.Center)}    .width("100%").height("100%")}
}

四、测试应用

1、启动仿真器

右上角选择设备,点击进入设备管理器,如果没有对应的仿真设备,需要下载安装,如果已经有,选择 Huawei_Phone 作为调试的仿真设备,点击启动。


2、界面测试

点击右上角启动键,启动项目。

有的时候会因为页面删除但是页面配置没清除完全导致运行失败,这个需要到项目启动类的配置文件里手动删除多出来的页面,启动类配置文件的路径是 DevEco-Studio\Test-Project\Harmony\entry\src\main\resources\base\profile\main_pages.json;

程序启动成功,运行效果如图:

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

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

相关文章

AJAX与axios框架

文章目录前言案例跨域访问总结❗前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 通过 ajax 进行前后端交互 案例 此项目用到了javaweb知识 首先创建JavaWeb项目编写代码&#xff1a; package ajax;import java.io.IOException; import java.util.Arr…

智能创造的幕后推手:AIGC浪潮下看AI训练师如何塑造智能未来

文章目录一、AIGC时代的算法与模型训练概览二、算法与模型训练的关键环节三、AI训练师的角色与职责四、AI训练师的专业技能与素养五、AIGC算法与模型训练的未来展望《AI训练师手册&#xff1a;算法与模型训练从入门到精通》亮点内容简介作者简介谷建阳目录《医学统计学从入门到…

Python设计模式 - 装饰模式

定义 装饰模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;用于在不修改原有类的情况下动态地扩展对象的功能。 结构抽象组件&#xff08;Component&#xff09;&#xff1a;定义对象的公共接口&#xff0c;使得客户端能以一致的方式处理未被装…

MySQL(188)如何使用MySQL的慢查询工具?

使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询。以下是详细深入的步骤和代码示例&#xff0c;帮助你使用MySQL的慢查询工具来进行查询分析和优化。 一、启用慢查询日志 首先&#xff0c;你需要确保MySQL的慢查询日志功能是启用的。慢查询日志记录了所有执行…

如何培养自己工程化的能力(python项目)

培养 Python 项目的工程化能力需要系统性训练&#xff0c;以下从基础到高阶的实践路径&#xff0c;结合具体案例和工具链&#xff0c;帮助你逐步进阶&#xff1a;一、夯实工程化基础能力​1. 规范代码与项目结构•​项目模板化​使用 cookiecutter生成标准项目结构&#xff0c;…

AI编程插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功能特性、性能表现、集成性、用户…

uniapp/uniappx实现图片或视频文件选择时同步告知权限申请目的解决华为等应用市场上架审核问题

在UNIAPP支持vue和nvue,在UNIAPPX支持uvue&#xff0c;安卓支持在选择图片或视频文件权限申请的时候自动同步告知权限申请目的。轻松解决在华为应用市场审核&#xff0c;要求告知权限申请目的或说明的问题。 UNIAPP相册图片视频选择器(安卓可以自定义界面样式)功能介绍&#x…

jupyter notebook如何打开其他盘目录

问题描述Jupyter Notebook 相信是我们学习 Python 避不开的一个工具。当我们使用 pip install notebook 安装 Notebook 之后&#xff0c;使用命令 jupyter notebook 启动服务&#xff0c;启动之后默认会在浏览器打开界面。我们会发现&#xff0c;这个界面默认在 C 盘下&#xf…

C语言深度剖析

一、关键字 1.1 最快的关键字-register register 这个关键字请求编译器尽可能将变量存在CPU内部寄存器中,而不是通过内存寻址以提高效率。 注意是:尽可能、而不是绝对 1.1.1 皇帝身边的小太监-寄存器 不知道什么是寄存器,那见过太监没有其实寄存器就是相当于。一个cpu的…

电脑使用“碎片整理”程序的作用

1.解决文件碎片化问题碎片整理的作用&#xff1a;将这些分散的文件片段重新整理、拼接&#xff0c;使其连续存储在硬盘的某个区域&#xff0c;减少文件的 “碎片化” 程度。2. 提升硬盘读写速度机械硬盘的特殊性&#xff1a;机械硬盘依赖磁头的物理移动来读取数据&#xff0c;若…

AI 软件工程开发 AI 算法 架构与业务

AI 软件工程开发 & AI 算法 & 架构与业务前言1.AI 软件工程开发1.1. AI Developer Studio &#xff08;playground级&#xff09;1.2. Agent & RAG1.3. LangChain & LangGraph1.4. MCP, Model Context Protocol1.5. Ollama1.6. Coze & Dify2.AI 算法2.1. G…

uniapp实现的圆形滚盘组件模板

采用 uniapp 实现的一款圆形滚盘示例组件模板, 支持 vue2、vue3&#xff0c;适配H5、微信小程序&#xff08;其他小程序未试过&#xff0c;可自行尝试&#xff09; 代码实现简约易懂&#xff0c;用户可根据自身需求下载模板&#xff0c;并进行扩展开发可到插件市场下载尝试&…

无须炮解,打开即是Pro版

聊一聊 文档或文件转图片&#xff0c;这个我有段时间没有推荐了。 今天发现了一款非常好用的图像格式转换编辑软件。 有需要的小伙伴请及时收藏&#xff0c;防止下次找不到。 软件介绍 全能图像格式转换工具 这是一款全能的图像转换软件&#xff0c;支持几乎所有的图像格式…

企业高性能web服务器——Nginx

Nginx介绍 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个邮件代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发&#xff0c;官方测试nginx能够支撑5万并发链接&#xff0c;并且cpu、内存等资源消耗却非常低&#xff0c;运行非常稳定。所以其特点是占有内存…

MCU控制ADAU1701,用System Workbench for STM32导入工程

作者的话 MCU控制ADAU1701&#xff0c;我有写一个文档详细讲步骤&#xff0c;里头用到了System Workbench for STM32这个软件&#xff0c;他是基于eclips内核的开发软件&#xff0c;一般来讲&#xff0c;设置好workspce工程就会出来&#xff0c;但是架不住就有设置好工程不出来…

SQL176 每个题目和每份试卷被作答的人数和次数

描述现有试卷作答记录表exam_record&#xff08;uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分&#xff09;&#xff1a;iduidexam_idstart_timesubmit_timescore1100190012021-09-01 09:01:012021-09-01 09:41:01812100290022021-09-01 …

构建第三方软件仓库

1 下载第三方软件到指定目录[rootServer_b ~]# mkdir software [rootServer_b software]# wget https://dldir1v6.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.18_250724_x86_64_01.rpm2 安装软件信息采集工具[rootServer_b software]# yum install createrepo -y [rootServer_b softw…

Linux 管道命令及相关命令练习与 Shell 编程、Tomcat 安装

2.实验目的掌握 Linux 管道命令及相关命令&#xff08;cut、sort、wc、uniq、tee、tr、split&#xff09;的使用方法。学会使用 Shell 编程实现基本的计算器功能。掌握在 CentOS 7 系统中安装 Tomcat 的方法。实验内容1. Linux 管道命令及相关命令练习1.1 管道命令定义&#xf…

蓝牙基础:FIFO(First-In-First-Out)缓存区

在蓝牙通信中&#xff0c;FIFO&#xff08;First-In-First-Out&#xff0c;先进先出&#xff09;缓存区是解决数据传输中“速度不匹配”和“时序异步”问题的核心机制&#xff0c;广泛应用于蓝牙芯片内部、协议栈各层级及主从设备交互中。其核心作用是临时存储数据&#xff0c;…

国内外主流源代码平台与高效开发指南

摘要 本文旨在为您提供一份实用的源代码获取与开发指南。我们将首先梳理国内外最主流的源代码托管平台&#xff0c;并重点介绍如何利用这些平台上的开源项目。接着&#xff0c;本文将为您规划一条针对初学者的“最快最性价比”的开发路径&#xff0c;从环境配置、项目管理到实…