当前位置: 首页 > news >正文

HarmonyOS之 组件的使用

一 容器

1.1 容器分类

  • Column表示沿垂直方向布局的容器。
  • Row表示沿水平方向布局的容器。

1.2 主轴和交叉轴

主轴:在Column容器中的子组件是按照从上到下的垂直方向布局的,其主轴的方向是垂直方向;在Row容器中的组件是按照从左到右的水平方向布局的,其主轴的方向是水平方向 

交叉轴:与主轴垂直相交的轴线,如果主轴是垂直方向,则交叉轴就是水平方向;如果主轴是水平方向,则交叉轴是垂直方向。

1.3 对齐

  • justifyContent:设置子组件在主轴方向上的对齐格式。
  • alignItems: 设置子组件在交叉轴方向上的对齐格式。

主轴方向的对齐(justifyContent):

Start:元素在主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。

Center:元素在主轴方向中心对齐,第一个元素与行首的距离以及最后一个元素与行尾距离相同。

End:元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。

SpaceBetween:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素与行首对齐,最后一个元素与行尾对齐。

SpaceAround:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。

SpaceEvenly:元素在主轴方向等间距布局,无论是相邻元素还是边界元素到容器的间距都一样。

交叉轴方向的对齐(alignItems)

Column容器的主轴是垂直方向,交叉轴是水平方向,其参数类型为HorizontalAlign(水平对齐):

  • Start:设置子组件在水平方向上按照起始端对齐。
  • Center(默认值):设置子组件在水平方向上居中对齐。
  • End:设置子组件在水平方向上按照末端对齐。

Row容器的主轴是水平方向,交叉轴是垂直方向,其参数类型为VerticalAlign(垂直对齐):

  • Top:设置子组件在垂直方向上居顶部对齐。
  • Center(默认值):设置子组件在竖直方向上居中对齐。
  • Bottom:设置子组件在竖直方向上居底部对齐。

二 基础组件:

2.1 Text

Text组件用于在界面上展示一段文本信息,可以包含子组件Span组件用于在界面上展示一段文本信息,可以包含子组件Span

@Entry
@Component
struct TextDemo {build() {Row() {Column() {Text('HarmonyOS')Text('HarmonyOS').fontColor(Color.Blue).fontSize(20).fontStyle(FontStyle.Italic).fontWeight(FontWeight.Bold).fontFamily('Arial')}.width('100%')}.backgroundColor(0xF1F3F5).height('100%')}
}

2.2 Image

Image组件用来渲染展示图片,它可以让界面变得更加丰富多彩。只需要给Image组件设置图片地址、宽和高,图片就能加载出来,示例如下:

Image($r("app.media.image2")).objectFit(ImageFit.Cover).backgroundColor(0xCCCCCC).width(100).height(100) 

2.3 TextInput

TextInput组件用于输入单行文本,响应输入事件。TextInput的使用也非常广泛,例如应用登录账号密码、发送消息等。和Text组件一样,TextInput组件也支持文本样式设置,下面的示例代码实现了一个简单的输入框:

TextInput().fontColor(Color.Blue).fontSize(20).fontStyle(FontStyle.Italic).fontWeight(FontWeight.Bold).fontFamily('Arial') 

2.4 Button

Button组件主要用来响应点击操作,可以包含子组件。下面的示例代码实现了一个“登录按钮”:

Button('登录', { type: ButtonType.Capsule, stateEffect: true }).width('90%').height(40).fontSize(16).fontWeight(FontWeight.Medium).backgroundColor('#007DFF')

2.5 List

List竖向列表,列表往往由多个条目组成,所以我们需要在List组件中写多个ListItem组件来构建列表,这就会导致代码的冗余。使用循环渲染(ForEach)遍历数组的方式构建列表,可以减少重复代码

@Entry
@Component
struct ListDemo {private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]build() {Column() {List({ space: 10 }) {ForEach(this.arr, (item: number) => {ListItem() {Text(`${item}`).width('100%').height(100).fontSize(20).fontColor(Color.White).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0x007DFF)}}, item => item)}}.padding(12).height('100%').backgroundColor(0xF1F3F5)}
}

2.6 Grid

Grid组件为网格容器,是一种网格列表,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。Grid组件一般和子组件GridItem一起使用,Grid列表中的每一个条目对应一个GridItem组件

@Entry
@Component
struct GridExample {private arr: String[] = ['0', '1', '2', '3']build() {Column() {Grid() {ForEach(this.arr, (day: string) => {ForEach(this.arr, (day: string) => {GridItem() {Text(day).fontSize(16).fontColor(Color.White).backgroundColor(0x007DFF).width('100%').height('100%').textAlign(TextAlign.Center)}}, day => day)}, day => day)}.columnsTemplate('1fr 1fr 1fr 1fr').rowsTemplate('1fr 1fr 1fr 1fr').columnsGap(10).rowsGap(10).height(300)}.width('100%').padding(12).backgroundColor(0xF1F3F5)}
}

2.7 AlertDialog

警告弹窗AlertDialog由以下三部分区域构成,对应下面的示意图:

  • 标题区:为可选的。
  • 内容区:显示提示消息。
  • 操作按钮区:用户做”确认“或者”取消“等操作。

Button('点击显示弹窗').onClick(() => {AlertDialog.show({title: '删除联系人', // 标题message: '是否需要删除所选联系人?', // 内容autoCancel: false, // 点击遮障层时,是否关闭弹窗。alignment: DialogAlignment.Bottom, // 弹窗在竖直方向的对齐方式offset: { dx: 0, dy: -20 }, // 弹窗相对alignment位置的偏移量primaryButton: {value: '取消',action: () => {console.info('Callback when the first button is clicked');}},secondaryButton: {value: '删除',fontColor: '#D94838',action: () => {console.info('Callback when the second button is clicked');}},cancel: () => { // 点击遮障层关闭dialog时的回调console.info('Closed callbacks');}})})

2.8 动画

Image(iconItem.imgRes).width(this.iconWidth).position({ x: iconItem.posX }).objectFit(ImageFit.Contain).animation({duration: 2000,tempo: 3.0,delay: iconItem.delay,curve: Curve.Linear,playMode: PlayMode.Normal,iterations: 1,onFinish: () => {      prompt.showToast({ message:"动画播放结束!!!" })}})

 2.9 Web

ArkUI为我们提供了Web组件来加载网页,借助它我们就相当于在自己的应用程序里嵌入一个浏览器,从而非常轻松地展示各种各样的网页

加载在线网页

@Entry
@Component
struct WebComponent {controller: WebController = new WebController();build() {Column() {Web({ src: 'https://developer.harmonyos.com/', controller: this.controller })}}
}

 加载本地网页

@Entry
@Component
struct SecondPage {controller: WebController = new WebController();build() {Column() {Web({ src: $rawfile('index.html'), controller: this.controller })}}
}

三 网络请求

3.1 生命权限

{"module" : {"requestPermissions":[{"name": "ohos.permission.INTERNET"}]}
}

3.2 导入http模块

import http from '@ohos.net.http';

 3.3 创建httpRequest对象

let httpRequest = http.createHttp();

3.4 发起http请求 

let url = "https://EXAMPLE_URL";
let promise = httpRequest.request(// 请求url地址url,{// 请求方式method: http.RequestMethod.POST,// 请求的额外数据。extraData: {"param1": "value1","param2": "value2",},// 可选,默认为60sconnectTimeout: 60000,// 可选,默认为60sreadTimeout: 60000,// 开发者根据自身业务需要添加header字段header: {'Content-Type': 'application/json'}});

3.5 处理响应结果

promise.then((data) => { if (data.responseCode === http.ResponseCode.OK) {console.info('Result:' + data.result);console.info('code:' + data.responseCode);}
}).catch((err) => {console.info('error:' + JSON.stringify(err));
});

四 三方库的使用

4.1 目前提供了两种途径获取开源三方库:

  • 通过访问Gitee网站开源社区获取,在Gitee中,搜索OpenHarmony-TPC仓库,在tpc_resource中对三方库进行了资源汇总,可以供开发者参考。
  • 通过HarmonyOS开发者官网提供的资源中心获取,进入HarmonyOS开发者官网选择 开发>DevEco Service,在DevEco Service页面下找到资源中心,在资源中心找到三方库入口

4.2 lottie动画三方库为例,lottie的安装 :通过ohpm执行对应的指令,将lottie安装到项目中。

ohpm install @ohos/lottie

4.3 卸载lottie

ohpm uninstall @ohos/lottie

4.4 引入lottie,通过import指令在项目中引入lottie到文件中。

import lottie from '@ohos/lottie'

4.5 构建Canvas画布

lottie解析JSON动画文件的数据需要基于Canvas 画布进行2D渲染,所以在加载JSON动画之前,要先初始化渲染上下文,并在画面中创建Canvas画布区域,将对应的渲染上下文renderingContext传递给Canvas。

// 初始化渲染上下文  
private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true) // 设置开启抗锯齿
private renderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings)  // 创建2D渲染上下文// 加载Canvas画布   
Canvas(this.renderingContext)...

4.6 使用lottie加载JSON动画

加载JSON动画需要用到loadAnimation方法,在方法中需配置相应的初始设置,包括渲染上下文、渲染方式以及JSON动画资源的路径等。可以直接使用lottie.loadAnimation方法,也可以用一个animationItem实例来接收返回的animationItem对象

// 用animationItem实例接收
let animationItem = lottie.loadAnimation({container: this.renderingContext,            // 渲染上下文renderer: 'canvas',                          // 渲染方式loop: 10,                                    // 设置为循环播放10次autoplay: true,                              // 是否自动播放,默认truepath: 'common/lottie/data.json',             // json路径})
//或者直接使用      
lottie.loadAnimation({container: this.renderingContext,            // 渲染上下文renderer: 'canvas',                          // 渲染方式loop: true,                                  // 默认为trueautoplay: true,                              // 是否自动播放,默认truepath: 'common/lottie/data.json',             // json路径})

4.7 lottie控制动画

// 播放、暂停、停止、销毁  可以使用lottie,也可以使用animationItem实例进行控制
lottie.play();        // 从目前停止的帧开始播放
lottie.stop();        // 停止播放,回到第0帧
lottie.pause();       // 暂停该动画,在当前帧停止并保持
lottie.togglePause(); // 切换暂停/播放状态
lottie.destroy();     // 删除该动画,移除相应的元素标签等。在unmount的时候,需要调用该方法// 播放进度控制
animationItem.goToAndStop(value, isFrame); // 跳到某个时刻/帧并停止。isFrame(默认false)指示value表示帧还是时间(毫秒)
animationItem.goToAndPlay(value, isFrame); // 跳到某个时刻/帧并进行播放
animationItem.goToAndStop(30, true);       // 例:跳转到第30帧并停止
animationItem.goToAndPlay(300);            // 例:跳转到第300毫秒并播放// 控制帧播放
animationItem.setSegment(5,15);             // 限定动画资源播放时的整体帧范围,即设置动画片段
animationItem.resetSegments(5,15);          // 重置播放的动画片段
animationItem.playSegments(arr, forceFlag); // arr可以包含两个数字或者两个数字组成的数组,forceFlag表示是否立即强制播放该片段
animationItem.playSegments([10,20], false); // 例:播放完之前的片段,播放10-20帧
animationItem.playSegments([[5,15],[20,30]], true); //例: 直接播放5-15帧和20-30帧// 动画基本属性控制
lottie.setSpeed(speed);         // 设置播放速度,speed为1表示正常速度
lottie.setDirection(direction); // 设置播放方向,1表示正向播放,-1表示反向播放// 获取动画帧数属性
animationItem.getDuration();    //获取动画时长

4.8 事件订阅

在一些特殊场景下,比如开始加载动画或者动画播放结束时,可能需要执行相应的操作,在lottie中提供了事件订阅和取消订阅的功能,当触发对应的event,会执行传入的回调函数,用户可以在回调函数中完成要实现的功能

// 订阅事件
animationItem.addEventListener(event,function(){// TODO something
})// 取消订阅事件
animationItem.removeEventListener(event,function(){// TODO something
})
// event事件类型
'enterFrame'   // 每进入一帧就会触发
'loopComplete' // 当前循环下播放(循环播放/非循环播放)结束时触发
'complete'     // 播放完成时触发
'segmentStart' // 播放指定片段时触发,playSegments、resetSegments等方法刚开始播放指定片段时会发出,如果playSegments播放多个片段,多个片段最开始都会触发。
'destroy'      // 销毁动画时触发
'data_ready'   // 数据准备完成
'DOMLoaded'    // 动画相关dom已经被添加
'error'        // 出现错误
'data_failed'  // 数据加载失败...

相关文章:

HarmonyOS之 组件的使用

一 容器 1.1 容器分类 Column表示沿垂直方向布局的容器。Row表示沿水平方向布局的容器。 1.2 主轴和交叉轴 主轴:在Column容器中的子组件是按照从上到下的垂直方向布局的,其主轴的方向是垂直方向;在Row容器中的组件是按照从左到右的水平方向…...

IAM:身份验证与授权

身份验证和授权可能听起来相似,但在核心功能方面它们是不同的。身份验证和授权是在用户尝试访问其资源时执行的安全过程。身份验证和授权在防止网络安全漏洞和加强组织的安全系统方面发挥着至关重要的作用。 验证:验证用户的身份 - 用户是谁&#xff1f…...

Linux——vi编辑器

目录 一、基本简介 二、命令模式下的常用按键 1、光标跳转按键 2、复制、粘贴、删除 三、编辑模式 四、末行模式 1、查找关键字并替换 2、保存退出 3、其他操作 五、模式切换 一、基本简介 1、最早可追随到1991年,全称为“Vi IMproved” 2、模式 ——命…...

【Linux学习笔记】权限

1. 普通用户和root用户权限之间的切换2. 权限的三个w2.1. 什么是权限(what)2.1.1. 用户角色2.1.2. 文件属性 2.2. 怎么操作权限呢?(how)2.2.1. ugo-rwx方案2.2.2. 八进制方案2.2.3. 文件权限的初始模样2.2.4. 进入一个…...

Aspose转pdf乱码问题

一、问题描述 ​ 在centos服务器使用aspose.word转换word文件为pdf的时候显示中文乱码(如图),但是在win服务器上使用可以正常转换 二、问题原因 由于linux服务器缺少对应的字库导致文件转换出现乱码的 三、解决方式 1.将window中字体(c:\windows\fonts)放到linux…...

table中的td内部的元素不能与td等高的问题

解决该问题的办法: td标签内部的元素使用table布局&#xff0c;但是需要注意的是td必须设置高度&#xff0c;高度为任意值都可以&#xff0c;虽然设置了高度&#xff0c;但是td依然会被内部内容的高度撑开 <template><table><tr><td><div class&q…...

Layui + Flask | 实现数据表格修改(案例篇)(09)

此案例内容比较多,建议滑到最后点击阅读原文,阅读体验更佳。后续也会录制案例视频,将在本周内上传到同名的 b 站账号。 接下来演示用 flask + layui 搭建一个学员信息管理的案例 这个案例将会利用 flask 做后端,layui table 组件做前端,基于 restful api 完成一个学员信息…...

BCC源码编译和安装

接前一篇文章&#xff1a;BCC源码下载 1. 进入源码根目录 进入到BCC源码根目录。命令及结果如下&#xff1a; $ cd bcc ~/eBPF/BCC/bcc$ ls cmake CONTRIBUTING-SCRIPTS.md docs images libbpf-tools man scripts src CMakeLists.txt …...

linux上gitlab备份与还原

三 Gitlab备份 1.gitlab安装 1.1 添加镜像地址 添加镜像地址的目的是为了提高国内用户软件下载的速度&#xff0c;编辑(新建)文件gitlab-ce.repo&#xff0c;指令&#xff1a; vi /etc/yum.repos.d/gitlab-ce.repo复制 输入&#xff1a; [gitlab-ce] namegitlab-ce # 清华…...

【精华】具身智能:人工智能的下一个浪潮

从符号主义到联结主义&#xff0c;智能体与真实世界的交互得到日益重视。上世纪五十年代的达特茅斯会议之后的一段时期内&#xff0c;对人工智能的研究主要限于符号处理范式&#xff08;符号主义&#xff09;。符号主义的局限性很快在实际应用中暴露出来&#xff0c;并催动了联…...

【线性回归、岭回归、Lasso回归分别预测患者糖尿病病情】数据挖掘实验一

Ⅰ、项目任务要求 任务描述&#xff1a;将“diabetes”糖尿病患者数据集划分为训练集和测试集&#xff0c;利用训练集分别结合线性回归、岭回归、Lasso回归建立预测模型&#xff0c;再利用测试集来预测糖尿病患者病情并验证预测模型的拟合能力。具体任务要求如下&#xff1a; …...

037:vue项目监听页面变化,动态设置iframe元素高度

第037个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…...

探索前端生成二维码技术:简单实用的实现方式

引言 随着智能手机的普及&#xff0c;二维码已经成为了现代生活中不可或缺的一部分。在许多场景下&#xff0c;我们都需要将某些信息或链接以二维码的形式展示出来。本文将介绍一种简单实用的前端生成二维码的技术&#xff0c;并给出具体的代码示例。 二维码生成原理 首先&a…...

python装13的一些写法

一些当你离职后&#xff0c;让老板觉拍大腿的代码 1. any(** in ** for ** in **) 判断某个集合元素&#xff0c;是否包含某个/某些元素 代码&#xff1a; if __name__ __main__:# 判断 list1 中是否包含某个/某些元素list1 [1,2,3,4]a any(x in [5,4] for x in list1) 输…...

黑马JVM总结(十八)

&#xff08;1&#xff09;G1_FullGC的概念辨析 SerialGC&#xff1a;串行的&#xff0c;ParallelGC&#xff1a;并行的 &#xff0c;CMS和G1都是并发的 这几种垃圾回收器的新生代回收机制时相同的&#xff0c;SerialGC和ParalledGC&#xff1a;老年代内存不足触发的叫FullGC…...

Android调用相机拍照,展示拍摄的图片

调用相机&#xff08;隐式调用&#xff09; //自定义一个请求码 这里我设为10010int TAKE_PHOTO_REQUEST 10010;int RESULT_CANCELED 0;//定义取消码//触发监听&#xff0c;调用相机image_camera.setOnClickListener(new View.OnClickListener() {Overridepublic void onCli…...

企业如何找媒体发稿能收录且不被拒稿,媒介盒子无偿分享

媒平台像头条、百家号、微信、微博、搜狐等平台&#xff0c;都支持全自助发稿&#xff0c;拥有庞大的用户群体。也正是因为这些平台的发展&#xff0c;衍生出了一大批自媒体KOL&#xff0c;影响力与传统媒体不相上下甚至更胜。 媒体宣发是企业营销的必要途径之一。软文是成本低…...

利用cms主题构造木马(CVE-2022-26965)

简介 CVE-2022-26965是Pluck CMS 4.7.16版本存在一个远程shell上传执行漏洞。 攻击者可利用此漏洞通过构造恶意的主题包进行上传并执行&#xff0c;未经授权访问服务器&#xff0c;造成潜在的安全隐患。 过程 1.打开环境&#xff0c;查看源码&#xff0c;发现login.php 2.进…...

【MTK】【WFD】手机投屏到投影仪不显示画面

问题分析: 在投屏过程中,有时候会出现WFD sink端回复的video 格式表不正确,sink表示是支持VESA(3fffffff),但是当手机根据协商结果得到最优分辨率并发送给sink端时,sink端看上去没有正常播放,其实实际上应该是不支持的。 比如我们这个问题就是CES表中的0001ffff,最大…...

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出 目录 多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...