一、內置組件是咩?
學過前端的都知道,一個組件就是由多個組件組成的,一個組件也可以是多個小組件組成的,組件就是一些什么導航欄、底部、按鈕......啥的,但是組件分為【自定義組件】跟【內置組件】
【自定義組件】就是我們想要一個什么樣的一塊元素,就用一堆內置組件通過我們自己設置屬性啥的,組合成一個【自定義組件】。
【內置組件】就是ArkTS原本就有的組件:圖片、按鈕、行元素、塊元素、視頻、音頻.....
二、內置組件的簡單寫法
組件名( )
有的組件需要往“( )”里帶參數,比如圖片組件要帶“路徑參數”;有的就不用,但是不用參數也必須帶上“( )”
然后如果要調整它的樣式,就在【組件名( )】后.屬性1( 值?).屬性2( 值 )......但是注意,有些屬性是所有組件通用的,有些是各個組件自己特有的
例子:
三、各個內置組件
1、圖片
圖片組件【Image( )】,只需要往( )里傳入圖片路徑即可用,但是有三種圖片路徑參數形式:
這里提示一下
我們的圖片一般就放在【resources】目錄下的【base.media】或【rawfile】
?$r() 一般對應【base.media】的圖片,當然也可以是別的目錄,寫的時候就是【app.別的目錄.圖片名】
?$rawfile() 則是對應【rawfile】的圖片,這個目錄就不能改了,要真的用到【rawfile】里有的圖片
示例:
第一種網絡圖片路徑例子
但其實只是在這個模擬運行器里可以顯示這個網絡地址的圖片,要是在真的模擬器或者手機上,就會顯示不出來,這是因為沒有申請網絡訪問權限
怎么申請網絡訪問權限?
官方文檔:文檔中心
找到在module.json5配置文件,在module下面復制這塊配置代碼(要了解為什么這么配置以后再說)
"requestPermissions": [{"name": "ohos.permission.INTERNET"} ],
第二種少用,就不演示了;
第三種本地路徑的例子:
然后我們會發現有時候圖片放大會有矩尺模糊、不好看,就需要用到圖片組件的一個【特有屬性】:.interpolation( )
當然如果我們記不住這么多屬性,可以查看鴻蒙的內置API文檔
點擊【Help】——>點擊【API Reference】就出來了API文檔
然后搜索組件名,點到【ArkTS】就能看到屬性詳情
看外邊框能看出一點差別
2、文字
文字組件【Text( )】
然后這里先提一下【resouces】這個目錄的文件結構
【base】可以理解為一個默認基礎陌路
下面的【en_US(英文)】【zh_CN(中文)】就是限定詞目錄,根據我們有什么限定詞目錄,將來翻譯一些文本文件時,就可以找到對應的限定詞目錄的json文件的對應的內容
然后【限定詞目錄】的string.json文件里有的變量,在【base】也必須要有
第一種靜態文字例子:
第二種根據本地源文件的變量顯示的文字例子:
那我們剛剛設置了MyName這個變量的英文版,怎么看英文版?看下圖
3、輸入框
輸入框組件【TextInput】
其中.type()屬性有以下屬性值
(注意,這些屬性只是輸入的【約束】,而非【校驗】,校驗需要我們自己手動)
名稱 | 描述 |
InputType.Normal | 基本輸入模式。支持輸入數字、字母、下劃線、空格、特殊字符 |
InputType.Password | 密碼輸入模式。支持輸入數字、字母、下劃線、空格、特殊字符 |
InputType.Email | 郵箱地址輸入模式。支持數字,字母,下劃線,以及@字符 |
InputType.Number | 純數字輸入模式 |
InputType.PhoneNumber | 電話號碼輸入模式。支持輸入數字、+、-、*、#? ? ?長度不限 |
例子:
然后我們來做一個案例,用輸入框輸入的不同數字,當成一個變量,這個變量根據輸入的數字來動態改變,同時還作為圖片的寬度來控制圖片大小
那么我們首先第一步:掛載、聲明當前頁面的這個變量
第二步:在用的地方 this.變量 就行了
看到這里,老鐵們是不是覺得很熟悉,跟vue的data差不多
然后注意這里有個報錯:輸入的是一個string類型,不能讓number類型的這個變量接收。可是我明明輸入框的類型是數字啊
這是因為輸入框其實一個“ 文本框 ”,即使輸入的是數字,也只是字符串類型的數字,所以要把輸入的 “ 字符串數字 ”轉化成 “ 真數字 ” ,方法跟java的字符串轉數字差不多【parseInt(字符串)】
還有,數字轉字符串是?.toFix() ,括號里的參數值是保留的小數點位,0就是沒有小數
4、按鈕
按鈕組件【Button】
其中.type( ) 有一下幾種值
名稱 | 描述 |
ButtonType.Capsule | 膠囊型按鈕(圓角默認為高度的一半) |
ButtonType.Circle | 圓形按鈕 |
ButtonType.Normal | 普通按鈕(默認不帶圓角) |
過于簡單,直接看代碼演示吧:
5、滑動條組件
這個玩意我們學HTML的時候就沒有了,ArkTS特有的滑動條組件【Slider()】
示例:
注意一點,粗細不是靠高度來調的
完整的
8、行容器跟列容器
這個更簡單,記住了【Column列容器】從上往下縱向排元素,【Row行容器】從左往右橫向排元素
用HTML理解:【Column】=【div】,【Row】=【block】
用uniapp理解:【Column】=【view】,【Row】=【text】
然后調整這兩個容器的布局通過下面這些屬性:
這一看,老鐵們熟悉得不能再熟悉了,對,就是CSS里面的【Flex彈性布局】啊!
就是有一點不同,主軸的屬性值要FlexAlign.排列值(center、SpaceBetween、SpaceEvenly......)
然后交叉軸,Column容器是HorizontaAlign.排列值,Row容器是VerticalAlign.排列值
【Column容器的主軸方向排列參數】
【Column容器的交叉軸方向排列參數】
【Row容器的主軸方向排列參數】
【Row容器的交叉軸方向排列參數】
示例:
【這里強調一點!!!!!!】
想要這些排列值生效,必須必須必須!!!把要排列的方向設置好寬或者高
比如我希望一個Row容器里的元素自左往右均勻排列,那么我首先必須設置主軸的長度,也就是寬度!!這樣才能根據寬度這個值來做參照,自動橫向排列;
我希望一個Column容器里的元素自上往下均勻排列,我就要先設置好高,這樣才能根據高度值做參照,自動縱向排列。
總結
四、樣式
這個ArkTS的樣式真是不想吐槽,對于我這種習慣了css、less、Vue......語法的人來說,真的麻煩得要死,大致上有些語法還是能用,但是還是有很多地方不一樣:
像素單位
相信各位注意到了,我前面那么多例子里,沒有出現過【px】、【vh】、【rpx】、【upx】這些常見單位
在ArkTS語法里,像素單位不需要寫了,“組件()”這里取而代之的單位有兩種形式:
? - 要么直接填數值
.height(100)
??- 要么填百分比,但是百分比形式必須要是字符串形式
.width('100%')
外邊距、內邊距
1、直接設置4個邊的外邊距的話,跟css一樣直接寫一個值就好
//內邊距 .padding(20)//外邊距 .margin(20)
2、如果你只要設置一邊的有邊距,在css的寫法是:margin-top: ...、padding-left: ...、......
或者:margin:? 上值?左值 下值 右值、padding: 上值?左值 下值 右值......
但是在ArkTS的寫法是往【.margin( )】傳入個對象參數,要哪個方向的邊距就在對象設置:{ 方向1:值 , 方向2:值 , ......?}
//左右有內邊距 .padding({ left: 10 , right: 10 })//上邊有外邊距 .margin({ top: 10 })
邊框
css的寫法賊雞兒簡單:
四邊都有邊框的話就是:border: 粗細? 類型(虛線、實現...)? 顏色
只要一邊有邊框就是:border-left: 粗細? 類型(虛線、實現...)? 顏色、border-top: 粗細? 類型(虛線、實現...)? 顏色 ......
但是ArkTS賊麻煩,記住了:
1、四邊都有邊框的話,顏色、粗細、類型啥的都有對應的屬性名:
.borderWidth(1) //粗細 .borderColor('#afefef') //顏色 .borderStyle(BorderStyle.Solid) //線類型
當然也可以通過傳對象的方式,把這些值全都放到一個對象傳給【border( )】
.border({style: BorderStyle.Solid, width: 1,color: Color.Gray })
2、只要一個邊的話,按各個屬性名的方式寫的話,每個屬性里都傳一個對象參數,對象里是對應的方向
.borderWidth({ bottom: 1 }) .borderColor({ bottom: '#afefef' }) .borderStyle({ bottom: BorderStyle.Solid })
或者按第二種傳對象的方式,每個對象的值還是對象
.border({style: { bottom: BorderStyle.Solid }, width: { bottom: 1 },color: { bottom: Color.Gray } })
3、然后圓角的話也是,四個角都是圓角的話就直接寫一個值
.borderRadius(20)
如果是只要單獨某幾個角,而不是四個角,還是傳對象值
.borderRadius({ topLeft: 20,topRight: 20,bottomLeft: 20,bottomRight: 20 })
然后圓角的值也可以作為對象值,直接傳入【border( )】
屬性值
還有,注意一些屬性值,跟我們css理解的屬性值不一樣,比如:
顏色,單詞類型的不是:blue、black、white、yellow......,而是Color.Blue、Color.Black、Color.White、Color.Yellow......
邊框的線的類型不是: solid、dotted、dashed,而是BorderStyle.Solid、BorderStyle.Dotted、 BorderStyle.Dashed
主軸排列justifyContent也不是:center、start、end、spaceBetween、spaceAround、spaceEvenly,而是FlexAlign.Center、 FlexAlign.Start、 FlexAlign.End、 FlexAlign.SpaceBetween、 FlexAlign.SpaceAround、 FlexAlign.SpaceEvenly
這里只說常見的,還有很多我就不一一列舉了,以后用到的時候翻閱文檔就知道了
五、循環
也很簡單,就是Vue里面的v-for,只不過Vue是在<標簽>里用v-for綁定數組名,它這個直接用ForEach()循環包住整個要循環的元素,也沒問題,轉換一下思維就好理解了
然后呢這玩意其實就是v-key
做個簡單示例:
首先定義一個簡單類
然后定義一個成員都是這個“ Item ”對象的數組
接下來直接循環它
有點難看,我們再調整一下樣式,根據前面學的【Column】、【Row】,我們把 “ 圖片 ” 和 “ 文字 ” 放到一個【Row容器】里左右排列,然后把文字部分的 “ item.name手機名字 ” 和? “ item.price手機價格 ” 放到一個【Column容器】里上下排列,然后再加點背景顏色、邊框、外邊距啥的,就nice了
但是還有問題!其實我們的元素是在整個頁面居中排列的,現在是因為數組的成員多才撐到了頂
我們去掉幾個元素,就會發現它是居中排列的
可是咱們要的是從頁面頂部自上往下排列啊,那就要設置整個包住中間這些元素的Column容器,沿著主軸方向從開頭排列【FlexAlign.Start】
用List()跟ListItem組件讓頁面可滑動
還沒完......我們發現寫完這個案例,沒辦法拖動屏幕看下面擋住的內容
就要加一個【List( )】這個組件包住【循環】,【List()】這個組件就是把這一塊作為可滑動的區域。然后這個【List( )】里面必須必須必須包含有一個【ListItem( )】組件,這兩組件暫時了解這么多夠了
說白了【List( )】就是代替【Column容器】
完整樣例代碼:
//ArkTS的類的定義方法
class Item {//定義變量成員name: stringimgUrl: stringprice: numberdiscount: number//構造函數//換成java的寫法:public Item(String name,String imgUrl,Int price)//discount: number = 0的意思是,可以不傳這個參數,不傳的話就默認是0constructor(name: string, imgUrl: string, price: number, discount: number = 0) {this.name = namethis.imgUrl = imgUrlthis.price = pricethis.discount = discount}
}
@Entry
@Component
struct Goods{private List: Array<Item> = [new Item('華為','https://gd-hbimg.huaban.com/a6d955ef4df395c734766c2ac56581123756c9c738a84-Jy0kKX_fw480webp',6999,500),new Item('蘋果','https://gd-hbimg.huaban.com/6b9a7c00dc59e3d60aad6d714556414597ba8a1889ad8d-ECDC3P_fw480webp',7900),new Item('黃金手機','https://gd-hbimg.huaban.com/4569250f8d17c98d95a22914a2ca3a2e6edbb64b53233-J8uXwa_fw480webp',10000),new Item('小米','https://gd-hbimg.huaban.com/49626e33a18e743dd935d21f80c503917e14a4c612f5c-3wjWTv_fw480webp',2000),new Item('黑莓','https://gd-hbimg.huaban.com/cfa621505f7b96b05f66851639bf6c0b941f0e3e2c24e-b4Y08n_fw480webp',3450),new Item('諾基亞','https://gd-hbimg.huaban.com/dbce23ae86918485a72c3b568d2827e1fa77087cddca-UJdsZc_fw480webp',6000)]build() {Column({space: 20}) {Text('岑梓銘黑心手機店').width('100%').height(40).fontSize(34).fontWeight(500).margin({top: 20,left: 70})List({ space: 10 }){ForEach(this.List,(item:Item , index:Number) => {ListItem(){Row({space: 30}){Image(item.imgUrl).height(120).width(80).margin({left: 30})Column(){Text(item.name).fontSize(28)Text('$ '+item.price.toFixed(0)).fontSize(23).fontColor(Color.Red)}.height(130).justifyContent(FlexAlign.SpaceEvenly)}}.backgroundColor("#efefef").width('90%').borderRadius(20).borderWidth(1).borderColor('#afefef').borderStyle(BorderStyle.Solid).borderRadius(20).border({style: BorderStyle.Solid,width: 1,color: Color.Gray,radius: 20})})}.width('100%')//List按比例配高度,不寫它的情況下就默認是0,那就默認自己配多高height就是多高//如果是1,那么就按比例,上面的元素是0,那么下面所有的高度都屬于這個配了.layoutWeight(1)的元素.layoutWeight(1).alignListItem(ListItemAlign.Center)}.width('100%')//【第一】要想以Column的縱向排列,就必須設置高度,這樣才能根據高度來排列.height('100%')//【第二】然后現在就可以根據Column的主軸的縱向,通過FlexAlign.Start從上往下排列了.justifyContent(FlexAlign.Start).backgroundColor('#afafaf')}
}
六、條件渲染
vue里的條件渲染是在<標簽元素>里綁定 【v-if】、【v-else】、【v-show】
而ArkTS這里是直接在循環里寫if-else,比較符合普通的編程語言的條件判斷
那么我們在上面的案例增加一個條件渲染:當有折扣的時候,顯示折扣,沒有就照常按原樣顯示
修改后的完整代碼:
//ArkTS的類的定義方法
class Item {//定義變量成員name: stringimgUrl: stringprice: numberdiscount: number//構造函數//換成java的寫法:public Item(String name,String imgUrl,Int price)//discount: number = 0的意思是,可以不傳這個參數,不傳的話就默認是0constructor(name: string, imgUrl: string, price: number, discount: number = 0) {this.name = namethis.imgUrl = imgUrlthis.price = pricethis.discount = discount}
}
@Entry
@Component
struct Goods{private List: Array<Item> = [new Item('華為','https://gd-hbimg.huaban.com/a6d955ef4df395c734766c2ac56581123756c9c738a84-Jy0kKX_fw480webp',6999,500),new Item('蘋果','https://gd-hbimg.huaban.com/6b9a7c00dc59e3d60aad6d714556414597ba8a1889ad8d-ECDC3P_fw480webp',7900),new Item('黃金手機','https://gd-hbimg.huaban.com/4569250f8d17c98d95a22914a2ca3a2e6edbb64b53233-J8uXwa_fw480webp',10000),new Item('小米','https://gd-hbimg.huaban.com/49626e33a18e743dd935d21f80c503917e14a4c612f5c-3wjWTv_fw480webp',2000),new Item('黑莓','https://gd-hbimg.huaban.com/cfa621505f7b96b05f66851639bf6c0b941f0e3e2c24e-b4Y08n_fw480webp',3450),new Item('諾基亞','https://gd-hbimg.huaban.com/dbce23ae86918485a72c3b568d2827e1fa77087cddca-UJdsZc_fw480webp',6000)]build() {Column({space: 20}) {Text('岑梓銘黑心手機店').width('100%').height(40).fontSize(34).fontWeight(500).margin({top: 20,left: 70})List({ space: 10 }){ForEach(this.List,(item:Item , index:Number) => {ListItem(){Row({space: 30}){Image(item.imgUrl).height(120).width(80).margin({left: 30})Column(){//當有discount這個成員時,顯示折扣價這些if( item.discount ){Text(item.name).fontSize(28)Text('原價:$ ' + item.price.toFixed(0)).fontSize(19).fontColor(Color.Gray)//這是添加刪除橫線,TextDecorationType還有下劃線、去掉線.......decoration({type: TextDecorationType.LineThrough})Text('折扣價:$ ' + (item.price - item.discount).toFixed(0)).fontSize(23).fontColor(Color.Red)Text('補貼:$ ' + item.discount.toFixed(0)).fontSize(20)}else{Text(item.name).fontSize(28)Text('$ '+item.price.toFixed(0)).fontSize(23).fontColor(Color.Red)}}.height(130).justifyContent(FlexAlign.SpaceEvenly)}}.backgroundColor("#efefef").width('90%').borderRadius(20).borderWidth(1).borderColor('#afefef').borderStyle(BorderStyle.Solid).borderRadius(20).border({style: BorderStyle.Solid,width: 1,color: Color.Gray,radius: 20})})}.width('100%')//List按比例配高度,不寫它的情況下就默認是0,那就默認自己配多高height就是多高//如果是1,那么就按比例,上面的元素是0,那么下面所有的高度都屬于這個配了.layoutWeight(1)的元素.layoutWeight(1).alignListItem(ListItemAlign.Center)}.width('100%')//【第一】要想以Column的縱向排列,就必須設置高度,這樣才能根據高度來排列.height('100%')//【第二】然后現在就可以根據Column的主軸的縱向,通過FlexAlign.Start從上往下排列了.justifyContent(FlexAlign.Start).backgroundColor('#afafaf')}
}