鸿蒙应用开发从入门到入行
第二天 - 开发工具与基础组件
导读:在本篇文章里,您将掌握鸿蒙开发工具DevEco的基本使用、ArkUI里的基础组件,并通过制作一个简单界面掌握使用
鸿蒙开发工具 - DevEco
工欲善其事,必先利其器。这节就让我们来看看以后会伴随我们鸿蒙开发的工具,如何下载使用
DevEco介绍
- HUAWEI DevEco Studio(以下简称DevEco Studio)是基于IntelliJ IDEA Community开源版本打造(Java开发者狂喜,与idea基本一样),为运行在HarmonyOS系统上的应用和服务(以下简称应用/服务)提供一站式的开发平台。
作为一款开发工具,除了具有基本的代码开发、编译构建及调测等功能外,DevEco Studio还具有如下特点:
- 高效智能代码编辑:支持ArkTS、JS、C/C++等语言的代码高亮、代码智能补齐、代码错误检查、代码自动跳转、代码格式化、代码查找等功能,提升代码编写效率。
- 多端双向实时预览:支持UI界面代码的双向预览、实时预览、动态预览、组件预览以及多端设备预览,便于快速查看代码运行效果。
- 多端设备模拟仿真:提供HarmonyOS本地模拟器,支持Phone等设备的模拟仿真,便捷获取调试环境。
- DevEco Profiler性能调优:提供实时监控能力和场景化调优模板,便于全方位的设备资源监测,采集数据覆盖多个维度,为开发者带来高效、直通代码行的调优体验
好的,上面内容太多太正式了,咱们提炼一下上面说的四点:
- 能写代码
- 能实时看代码效果
- 能用模拟器模拟真机来调试
- 提供了性能分析工具,帮助app性能调优
运行环境要求
为保证DevEco Studio正常运行,建议电脑配置满足如下要求:
- 操作系统:Windows10 64位、Windows11 64位
- 内存:16GB及以上
- 硬盘:100GB及以上
- 分辨率:1280*800像素及以上
- 操作系统:macOS(X86) 12/13/14 macOS(ARM) 12/13/14
- 内存:8GB及以上
- 硬盘:100GB及以上
- 分辨率:1280*800像素及以上
- 注意:windows版内存需16GB以上,mac需8GB以上,不满足的话可能开发过程会相对比较卡。
下载与安装
- https://developer.huawei.com/consumer/cn/deveco-studio/
- 安装过程就不详细介绍了,总之Windows版就是下一步下一步直到完成(默认安装到C盘,若不愿意则自己改一下安装位置再下一步),Mac版只需要拖入应用程序(Applications)文件夹即可
切换为中文环境
- DevEco安装后界面默认是英文的,如果更习惯看中文界面,可通过如下方式设置
windows版修改:
- 进入项目后,菜单栏选File -> Setting -> Plugins -> 搜索
chinese
-> 启用 -> 重启DevEcho后生效
- 进入项目后,菜单栏选File -> Setting -> Plugins -> 搜索
mac版修改
与windows版区别仅在于第一步不是从菜单栏File进入,而是在菜单栏苹果图标后第一项进入
创建项目
- 若首次打开DevEco Studio,请点击Create Project(新建项目)创建工程。如果已经打开了一个工程,请在菜单栏选择File(文件) > New(新建) > Create Project(新建项目)来创建一个新工程。
- 选择Application应用开发(Application下面的Atomic Service是元服务开发,后面学),选择模板“Empty Ability”,点击Next进行下一步配置。
- 进入配置工程界面,Compatible SDK选择“5.0.0(12)”(默认就是它,这就是鼎鼎大名的纯血鸿蒙版),其他参数保持默认设置即可。
- 点击Finish,工具会自动生成示例代码和相关资源,等待工程创建完成。
项目区域说明
如上图所示:
左侧的大区域为项目资源管理区,项目的一切资源都在这里展示
- 早期我们只需要关注
entry
这个文件夹即可,我们早期的所有代码都在这个文件夹里编辑 - 其中
entry->src->main->ets->pages
这个文件夹早期会成为我们写页面的地方 - 其中
entry->src->main->resource
这个文件夹将来会作为我们放图片资源和国际化的地方 - 其他的文件就不一一介绍,猫林老师不喜欢像其他教程一样上来就把所有文件功效列出来,没意义。看完也记不住,还不如咱们用到什么就介绍什么,然后这些文件自然而然就知道是啥意思了
- 早期我们只需要关注
- 中间是代码编辑区域,以后写代码就是在这里了,如果你觉得中间区域不够大,可以把左侧面板缩小甚至折叠
右侧是侧边工具栏,前期我们最常用的就是
预览器
,这个地方就是实时查看界面效果的地方,并且代码一改,预览器自动刷新- 底部区域我们前期暂时用不上,将来可能需要在终端里输入命令下载一些三方包、日志里查看console.log的输出等。但目前无须过于关注
Tips:新建项目后,页面代码里默认就会有个Text
,并且打开预览器会看到Hello World
,尝试修改Text
小括号里的内容,给它一个字符串,试试看预览器会否有变化呢?
ArkTS语法说明
- ArkTS是HarmonyOS优选的主力应用开发语言,ArkTS是在TypeScript(简称TS)生态基础上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和性能。
这里做个简单说明:TypeScript相当于扩展了JavaScript,多了些语法。而ArkTS又相当于扩展了TypeScript,关系如下图
<img src="https://gitee.com/xpzll/newtypora/raw/master/noteimg/202408021035014.png" alt="image-20240731163451613" style="zoom: 33%;" />
从上图可以看到JS、TS拥有的语法,ArkTS也有,甚至更多(主要添加了一些声明式UI语法)。
- 注:实际上出于稳定、安全的目的,有部分语法、接口在ArkTS里也不允许使用。但是大家都放心,这些语法、接口甚至在JS里大家也用的少,例如
Object.getOwnPropertyDescriptor
之类的这种方法。所以大家可以四舍五入默认TS的语法ArkTS都能用即可
- 注:实际上出于稳定、安全的目的,有部分语法、接口在ArkTS里也不允许使用。但是大家都放心,这些语法、接口甚至在JS里大家也用的少,例如
最后,猫林老师要说明一点非常重要的事:本教程不会做基础语法讲解
- 猫林老师默认本文章的读者至少是懂:变量、常量、分支语句、循环语句、函数、数组、对象、类、接口这些内容的
纳尼?你毛都不会?那麻烦出门左转买包华子抽根烟冷静下。然后坐等猫林老师将来出语法教程。
- 如果你懂
TS
,那么可以说接下来的语法你毫无压力,只是随着学习了解一些ArkTS新增的语法(这个猫林老师会讲) - 如果你仅仅只懂
JS
,其实问题也不大。TS
本身在语法层面跟JS
区别不大,而且语言是相通的,只要你明白变量、常量、分支语句等等这些概念,其实到时候一看猫林老师的代码,就知道是啥意思。 就好比下面这句代码
let age: number = 16
- 你用屁股想都知道是声明了一个变量,变量类型是number,值是16
- 退一万步说,假设后面的教程里如果有某个语法你看不懂是什么意思,也可以搜一搜,或者利用AI解答一下,或者直接留言问猫林老师也可以的。绝对不会影响学习进度和体验。而且这样相当于在新知识中补全自己的TS水平,猫林老师觉得大赞呢!
好了,废话不多说。接下来,我们正式进入到鸿蒙开发的世界!
ArkUI - 基础组件
ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发
- 上句是官网对ArkUI的说明
- 这里猫林老师提炼一下:ArkUI相当于是华为内置好的UI组件库,我们可以用这些不同的组件组合在一起构成精美的页面
代码结构
在正式学习组件前,我们先聊聊默认生成的代码结构以便帮助你更好的入门,每部分具体内容请看下图
- 在这张图里,零基础的老铁们暂时不用管其他的是什么意思。你只要知道一个:build函数不能删,且它里面是写界面的地方
Text组件
- Text是我们新建项目后在build里见到的第一个组件。看名字都知道,这货肯定是用来显示文本的,就像上图,我们能看到文字,就是因为在
build
里有一个Text
用法
Text('文字内容')
- 注意,小括号里给字符串,
单引号
、双引号
、模板字符串反引号
都可
- 注意,小括号里给字符串,
自己动手试试
来到
pages/index.ets
文件,把build
里的代码都删掉,直接写一个Text
试试,例如@Entry @Component struct Index { build() { Text('猫林老师') } }
效果如下
通过效果我们发现
Text
果然能显示文本,但是如果觉得文本默认样式不是你喜欢的,你还可以对它修改属性,以后组件的属性修改语法统一都是组件() { } .属性(属性值)
- 注意:在ArkTS里,所有的属性都是以方法形式存在的,所以也称之为属性方法
那
Text
有哪些常用属性呢?这里猫林老师列一下fontSize
- 字体大小,默认为16vp(vp是一种自适应单位,会自动根据设备不同转换成不同的像素,不写单位默认就是vp)
fontColor
- 字体颜色
- 支持16进制颜色,支持RGB颜色,以及华为提供的内置颜色枚举
fontWeight
- 字体粗细,支持数字,以及华为提供的枚举
代码例
@Entry @Component struct Index { build() { Text('猫林老师') .fontSize(32) // 设置字体大小为32 .fontColor('#f00') // 设置字体颜色为红色,也可以写 'rgb(255,0,0)',效果一样 .fontWeight(700) // 设置字体粗细为700(加粗了) } }
- 之前猫林老师说了,颜色可以写16进制,也可以写rgb,所以上述代码你换成
.fontColor('rgb(255,0,0)')
效果也一样,但要注意的是,他们都得是字符串,即被引号包起来 但是像上述代码,文字颜色、文字粗细这种要么是写字符串,要么写数字的,其实阅读起来并不直观。所以华为还提供了枚举来修改
@Entry @Component struct Index { build() { Text('猫林老师') .fontSize(32) .fontColor(Color.Red) .fontWeight(FontWeight.Bold) } }
- 这里的
Color.Red
相当于是'#f00'
或'rgb(255,0,0)'
,但是用这种华为提供的枚举写法,会更加便于阅读,一看就知道是红色 - 这里的
FontWeight.Bold
相当于是700
,但是一看Bold就是加粗 - 注意:华为内置枚举的首字母一般都大写
- 这里的
在
DevEco
开发工具里,其实只要一写好枚举类型再按一个点,它会自动出对应的值的提示,选中一个就好,如下图
根组件
在学完
Text
后,我们发现,当我们尝试要多加一个Text
后,会报错,如下图这是为什么呢?难道不允许猫林老师很帅?
- 当然不是!!
- 这是因为在鸿蒙开发里,也遵循一个页面(或一个自己封装的组件)必须有且只有一个根组件的规定
那么,什么是根组件呢?
- 根组件就是包住当前页面所有内容的最外部容器
- 一般都是用布局组件来作为根组件(布局组件接下来就会讲两个:Column与Row,其他的布局组件学一个记一个)
所以上图报错,正是因为我们有两个Text,但它并没有一个包住他们的最外部容器
- 解惑:为什么只有1个
Text
时不报错呢?因为只有1个时,它既是根组件又是内容
- 解惑:为什么只有1个
解决办法:在build里面,两个Text最外面包一个
Column
build() { Column() { Text('猫林老师') .fontSize(32) .fontColor(Color.Red) .fontWeight(FontWeight.Bold) Text('很帅') } }
此时效果如下
Column组件
- Column组件是ArkUI里专门用来做纵向布局的容器组件
- 特点:能让它的子组件从上到下进行排列
用法:
Column () { // ... }
- 所以上例中,我们给两个
Text
一旦加上Column
这个父组件后,他们就一上一下排列了 - 一般情况下,页面的根容器需要铺满整个页面,所以需要给宽高。如果不给,默认是它的内容多大,它就多大
注意:猫林老师在这里给大家提炼一个ArkUI的特点:任何组件不给宽高默认都无宽高,全是靠内容自动撑开
所以一般情况下,我们还会给
Column
设置宽高,继续修改上述案例,添加宽高Column() { Text('猫林老师') .fontSize(32) .fontColor(Color.Red) .fontWeight(FontWeight.Bold) Text('很帅') } .width('100%') .height('100%')
此时结果如下
- 加完Column这个根容器后,我们还发现两个文字都水平居中了,原因跟
Column
的默认排列方式有关,所以我们来了解下 首先需要了解在鸿蒙开发中的坐标系,分为两个轴。
- 如图,左上角为坐标轴起点(原点),从左至右为X轴,从上至下为Y轴
- 然后在
Column
布局容器里,因为默认情况下Column是让子组件从上往下排列,所以把y轴这根轴称之为主轴,x轴称之为交叉轴 - 默认情况下,Column会让子组件在主轴方向,默认是从起点开始排列对齐,而在交叉轴方向是默认居中
- 因此,我们会发现上述案例两个Text,在Y轴最顶端(因为Y是主轴),在X轴居中(因为X是交叉轴)
- 能否修改子组件在主轴、交叉轴上的排列呢?当然可以,请看下图
设置主轴方向的排列方式
发现通过justifyContent属性可以设置子组件在主轴方向排列方式,一共有六种取值
- FlexAlign.Start:默认值。在主轴起点依次排列
- FlexAlign.Center:主轴居中
- FlexAlign.End:主轴终点
- FlexAlign.SpaceBetween: 子组件之间平分间距,并且首组件和尾组件分别在起点和终点
- FlexAlign.SpaceAround:子组件之间平分间距,并且首尾组件距离起点和终点也有间距,首尾间距是组件间距的一半
- FlexAlign.SpaceEvenly: 子组件之间平分间距,并且首尾组件距离起点和终点也有间距,他们间距全部相等
- 题外话:会CSS的同学会发现这无非就是Flex布局,只不过比CSS的Flex布局多了
SpaceEvenly
如果你想主轴方向排列自己设置子组件之间的间距,可以用传入space参数,用法如下
Column ({ space: 10 }) { // 子组件 }
- 若子组件有三个,则会如下图排列(其中的space距离就是上述代码传入的10)
设置子元素在交叉轴方向的排列(通过设置AlignItems属性)
发现通过HorizontalAlign属性可以设置子元素在交叉轴方向排列方式,一共有三种取值
- 注意:Horizontal是水平的意思,所以这里很明显就是在水平方向排列。
- HorizontalAlign.Start: 在水平方向起点对齐
- HorizontalAlign.Center:在水平方向居中对齐
- HorizontalAlign.End:在水平方向终点对齐
检验所学:
- 思考,如何让上述案例两个文字,无论垂直还是水平方向都居中呢?
- 没错,就是给
Column
设置justifyContent
属性,并且值为FlexAlign.Center
,即能实现在主轴(垂直方向)居中。然后设置AlignItems
属性为HorizontalAlign.Center
,其中AlignItems可以不用设置,因为默认就是交叉轴居中 代码如下
Column() { Text('猫林老师') .fontSize(32) .fontColor(Color.Red) .fontWeight(FontWeight.Bold) Text('很帅') } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center)
Row组件
- Row组件是ArkUI里专门用来做横向布局的容器组件
- 特点:能让它的子组件从左到右进行排列
- 用法也跟Column差不多,只不过他们主轴不一样。Row的主轴是X轴,交叉轴是Y轴
设置主轴方向的排列方式
- 通过上图发现,属性依然叫justifyContent,取值依然是
HorizontalAlign
的六个值,效果一样,只不过变成了在x轴(水平方向排列)
- 通过上图发现,属性依然叫justifyContent,取值依然是
设置交叉方向的排列
- 注意:设置交叉轴,依然是用
AlignItems
属性,但是取值变成了VerticalAlign
,毕竟它就是设置垂直方向,所以叫VerticalAlign
- 注意:设置交叉轴,依然是用
这时候有懒货说了,老师,一会
HorizontalAlign
,一会VerticalAlign
,我记不住怎么办?这时候不得不说DevEco
的强大提示功能了,你只要一写AlignItems
它就会给你提示填什么内容,如下图
同样的,如果想自己手动设置主轴方向上子组件的间距,也可以用
space
Column ({ space: 10 }) { // 子组件 }
- 动手强化:试试,把上述案例的根容器变成
Row
看看效果,并尝试改它的主轴和交叉轴排列
Image组件
- 专门用来显示图片的组件
- Image支持png、jpg、jpeg、bmp、svg、webp、gif和heif类型的图片格式
- 可以加载本地图片(项目内图片资源)、网络图片
- 但如果要加载网络图片,运行到真机或浏览器必须配置申请网络权限
接下来我们先演示加载本地图片,本地图片一般会放在
entry/src/main/resource/base/media
文件夹- 可以看到,新建完项目后
media
里已经有一些默认图片了,那么如何显示这里的图片呢?需要用到内置的$r
函数 例
Image($r('app.media.startIcon'))
- 这就代表找到media文件夹里的
startIcon.png
这张图片了,注意:不用加后缀 - 前面的
app.media
即代表找到media
文件夹,后面就填这个文件夹内的图片名即可
- 这就代表找到media文件夹里的
效果如下
- 但此时发现,图片铺满了屏幕。原因是在ArkUI的所有组件里,如果不给宽高默认会以内容作为最终宽高,因此Image没给宽高会用图片实际宽高作为Image的宽高,而这张图片过大,所以撑满屏幕都还没显示完
继续设置宽高后则正常
- 这里同学们可能会发现猫林老师只给了宽度没给高度,因为这就像css里的一样,图片给了宽度,它会自动按原图比例计算出高度
我们再试试让
Image
加载网络图片Image('https://www-file.huawei.com/-/media/corporate/images/home/logo/huawei_logo.png') .width(100)
- 发现,仅仅只需要在
Image
里传入图片网址字符串即可 但是这时候有同学疑惑了:你这个老哔登,之前不是说要申请网络权限吗?咋这会不需要了?
<img src="https://i0.hdslb.com/bfs/archive/bcaf75b087f656bbd6a8b9bb08b2c96b02475337.jpg" alt="点击查看图片来源" style="zoom:50%;" />
- 发现,仅仅只需要在
- 如果你是如此质疑我,我表示:质疑的好!说明你们刚刚认真学习了!但是要注意:我说的是真机或模拟器运行时需要申请网络权限,而现在我们仅仅只是预览,所以能看到。
P.S:其实在之前的DevEco中,即是是预览也要配置网络权限,但是在
Preview版
后,华为为了方便大家快速做布局看效果,让大家预览器界面也能直接看到网络图片- 关于如何申请网络权限,后面再讲
TextInput组件
- 文本输入框
- 作用:专门用来让用户进行输入的
语法
TextInput( { placeholder: '占位符', text: '默认值' } )
- 注:如果默认值为空,则显示占位符,否则不显示
常用属性:
type:设置输入框类型
常用值有:
- InputType.Normal:默认值,普通文本输入框,支持输入数字、字母、下划线、空格、特殊字符
- InputType.Password:密码输入框
- InputType.Email: 邮箱地址输入模式。支持数字,字母,下划线,以及@字符(会自动校验内容只能存在一个@字符)
- InputType.Number: 纯数字输入模式。
- InputType.PhoneNumber:电话号码输入模式。支持输入数字、+ 、-、*、#,长度不限。
- maxLength:设置最大允许输入的字符数
- 其他暂时不介绍,用到再说,还是那句话,我不喜欢列一堆东西出来,暂时用不到大家看了也记不住
Button组件
- 按钮组件
- 作用:让用户点击或者触摸
语法
Button('按钮名')
默认情况下依然是内容撑开,所以一般Button需要给宽高
- 我们发现,默认情况下Button是胶囊型的(也即有圆角),如果不喜欢还可以设置样式
属性
type:设置按钮样式,当按钮宽100的情况下,三种样式如下
ButtonType.Capsule: 默认值,胶囊型
ButtonType.Circle: 默认值,圆形
ButtonType.Normal: 普通型,就是没圆角
总结今天内容
DevEco介绍
- 一款牛逼的鸿蒙开发工具
DevEco下载与安装
- 略
DevEco新建项目后,目前写代码的地方在?
entry->src->main->ets->pages
放图片的地方在哪?
entry/src/main/resource/base/media
布局页面的代码写在哪个函数内?
- build
基础组件
Text
- 文本组件,展示一段文本
属性:
- fontColor
- fontSize
- fontWeight
Column:
- 布局组件,能让子组件从上到下布局(沿着y轴布局)
如果要自主设置子组件的间距,可以传入
space
Column({ space: 间距数 })
属性有
justifyContent:设置子组件在主轴的排列方式
- FlexAlign.Start:在主轴起点
- FlexAlign.Center:在主轴居中
- FlexAlign.End:在主轴终点
- FlexAlign.SpaceBetween:首尾子组件在主轴起点和终点无间距,并且每个子组件之间平分间距
- FlexAlign.SpaceAround:每个子组件之间平分间距,首尾子组件在主轴起点和终点也有间距且间距是子组件之间的一半
- FlexAlign.SpaceEvenly:每个子组件之间平分间距,首尾子组件在主轴起点和终点也有间距且间距相等
alignItems: 设置子组件在交叉轴排列方式(用在Column代表设置水平方向)
- HorizontalAlign.Start:子组件在水平方向起点对齐
- HorizontalAlign.Center:子组件在水平方向居中对齐
- HorizontalAlign.End:子组件在水平方向终点对齐
Row:
- 布局组件,能让子组件从左到右布局(沿着x轴布局)
如果要自主设置子组件的间距,可以传入
space
Row({ space: 间距数 })
属性方法有
justifyContent:设置子组件在主轴的排列方式
- FlexAlign.Start:在主轴起点
- FlexAlign.Center:在主轴居中
- FlexAlign.End:在主轴终点
- FlexAlign.SpaceBetween:首尾子组件在主轴起点和终点无间距,并且每个子组件之间平分间距
- FlexAlign.SpaceAround:每个子组件之间平分间距,首尾子组件在主轴起点和终点也有间距且间距是子组件之间的一半
- FlexAlign.SpaceEvenly:每个子组件之间平分间距,首尾子组件在主轴起点和终点也有间距且间距相等
alignItems: 设置子组件在交叉轴排列方式(用在Row代表设置垂直方向)
- VerticalAlign.Start:子组件在水平方向起点对齐
- VerticalAlign.Center:子组件在水平方向居中对齐
- VerticalAlign.End:子组件在水平方向终点对齐
Image组件
- 显示一张图片
- 可以显示本地也可以显示网络
- 真机或模拟器运行,显示网络图片需要申请权限
- 用
$r
加载本地图片
TextInput组件
- 输入框
- 可以传入
placeholder
属性设置占位符,也可以用text
属性绑定输入内容 type属性方法修改输入框类型
- InputType.Normal:默认值,普通文本输入框
- InputType.Password:密码输入框
- InputType.Email: 邮箱地址输入模式
- InputType.Number: 纯数字输入模式。
- InputType.PhoneNumber:电话号码输入模式。
Button组件
- 按钮
type属性方法设置样式
- ButtonType.Capsule:默认值,胶囊型
- ButtonType.Circle:圆形
- ButtonType.Normal:无圆角
课后练习
单选题
需要在主轴上使第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半,通过下列那种方式设置?
A. justifyContent(FlexAlign.SpaceBetween)
B. justifyContent(FlexAlign.SpaceAround)
C. justifyContent(FlexAlign.SpaceEvenly)
D. justifyContent(FlexAlign.Center)
当开发者需要使用TextInput完成一个密码输入框,推荐设置type属性方法为下面哪个值?
A. InputType.Normal
B. InputType.Password
C. InputType.Email
D. InputType.Number
Image如果要加载
entry/src/main/resource/base/media/my.png
这张图片,下面哪种写法是对的?A. $r('my.png')
B. $r('app.media.my.png')
C. $r('app.media.my')
D. $r('media.my')
多选题
下面哪些属于属性方法?
A. fontSize() B. onClick() C. width() D. height()
判断题
- 在Column容器中的子组件默认是按照从上到下的垂直方向布局的,其主轴的方向是垂直方向,在Row容器中的组件默认是按照从左到右的水平方向布局的,其主轴的方向是水平方向。
扩展练习题
利用今天所学制作一个界面,要求如图
- 提示:可以把今天所学的组件全用上,建议分析界面先确定整体大容器,由外而内
- 这个案例在下一天课程里也会先进行讲解,届时大家可以对照一下思路是否一致呢?
互动环节
- 经过今天的学习,你觉得ArkTS语法和你所熟悉的哪款语言比较像呢?评论区留言欢迎说说
- 如果有什么对课程的建议和想法也请欢迎说说
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。