不同的屏幕尺寸,如何適配?鴻蒙提供了自適應(yīng)布局和響應(yīng)式布局。
| 名稱 | 簡介 |
|---|---|
| 自適應(yīng)布局 | 拉伸屏幕,頁面的位置關(guān)系沒有發(fā)生變化。自適應(yīng)布局常常需要借助Row組件、Column組件或Flex組件實現(xiàn)。當前自適應(yīng)布局能力有7種:拉伸能力、均分能力、占比能力、縮放能力、延伸能力、隱藏能力、折行能力。 |
| 響應(yīng)式布局 | 拉伸屏幕,頁面的位置關(guān)系發(fā)生變化。響應(yīng)式布局常常與GridRow組件、List組件、Swiper組件或Tabs組件搭配使用。響應(yīng)式布局能力有3種:斷點、媒體查詢、柵格布局。 |
自適應(yīng)布局
下面介紹自適應(yīng)布局的7種能力。自適應(yīng)布局的7種能力需要牢記于心。
拉伸能力
父組件尺寸發(fā)生變化,增加或減小指定組件的尺寸。
| 屬性 | 默認值 | 描述 |
|---|---|---|
| flexGrow | 0 | 父容器寬度大于所有子組件寬度的總和,子組件按照比例分配父容器的多余空間。 |
| flexShrink | 1 | 父容器寬度小于所有子組件寬度的總和。子組件按照比例收縮分配父容器的不足空間。 |
| flexBasis | 'auto' | 設(shè)置組件在Flex容器中主軸方向上基準尺寸。'auto'意味著使用組件原始的尺寸,不做修改。flexBasis屬性不是必須的,通過width或height也可以達到同樣的效果。當flexBasis屬性與width或height發(fā)生沖突時,以flexBasis屬性為準。 |
下面的示例中,頁面由中間的圖片以及兩側(cè)的留白區(qū)組成,各區(qū)域的屬性配置如下:
- 中間內(nèi)容區(qū)的寬度設(shè)置為400vp,同時將flexGrow屬性設(shè)置為1,flexShrink屬性設(shè)置為0。
- 兩側(cè)留白區(qū)的寬度設(shè)置為150vp,同時將flexGrow屬性設(shè)置為0,flexShrink屬性設(shè)置為1。
父容器的基準尺寸是700vp(150vp+400vp+150vp)??梢酝ㄟ^拖動底部的滑動條改變父容器的尺寸,查看布局變化。 - 當父容器的尺寸大于700vp時,父容器中多余的空間全部分配給中間內(nèi)容區(qū)。
-
當父容器的尺寸小于700vp時,左右兩側(cè)的留白區(qū)按照“1:1”的比例收縮。
示例圖
@Entry
@Component
struct FlexibleCapabilitySample1 {
@State containerWidth: number = 402
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽纭? @Builder slider() {
Slider({ value: this.containerWidth, min: 402, max: 1000, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.onChange((value: number) => {
this.containerWidth = value;
})
.position({ x: '20%', y: '80%' })
}
build() {
Column() {
Column() {
Row() {
// 通過flexGrow和flexShrink屬性,將多余的空間全部分配給圖片,將不足的控件全部分配給兩側(cè)空白區(qū)域。
Row().width(150).height(400).backgroundColor('#FFFFFF')
.flexGrow(0).flexShrink(1)
Image($r("app.media.illustrator")).width(400).height(400)
.objectFit(ImageFit.Contain)
.backgroundColor("#66F1CCB8")
.flexGrow(1).flexShrink(0)
Row().width(150).height(400).backgroundColor('#FFFFFF')
.flexGrow(0).flexShrink(1)
}
.width(this.containerWidth)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
}
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
如果期望將父容器的剩余空間全部分配給某空白區(qū)域時,也可以通過Blank組件實現(xiàn)。注意僅當父組件為Row、Column、Flex組件時,Blank組件才會生效。

@Entry
@Component
struct FlexibleCapabilitySample2 {
@State rate: number = 0.8
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽? @Builder slider() {
Slider({ value: this.rate * 100, min: 30, max: 80, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.onChange((value: number) => {
this.rate = value / 100;
})
.position({ x: '20%', y: '80%' })
}
build() {
Column() {
Column() {
Row() {
Text('飛行模式')
.fontSize(16)
.width(135)
.height(22)
.fontWeight(FontWeight.Medium)
.lineHeight(22)
Blank() // 通過Blank組件實現(xiàn)拉伸能力
Toggle({ type: ToggleType.Switch })
.width(36)
.height(20)
}
.height(55)
.borderRadius(12)
.padding({ left: 13, right: 13 })
.backgroundColor('#FFFFFF')
.width(this.rate * 100 + '%')
}
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
均分能力
父容器縮放,子組件的尺寸不變,只是中間的間距或者留白按照比例縮放。均分能力可以通過將Row組件、Column組件或Flex組件的justifyContent屬性設(shè)置為FlexAlign.SpaceEvenly實現(xiàn)。
占比能力
子組件的寬高按照預(yù)設(shè)的比例,隨父容器組件發(fā)生變化。占比能力通常有兩種實現(xiàn)方式:
- 將子組件的寬高設(shè)置為父組件寬高的百分比。
-
設(shè)置權(quán)重layoutWeight屬性。
示例圖
@Entry
@Component
struct ProportionCapabilitySample {
@State rate: number = 0.5
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽? @Builder slider() {
Slider({ value: 100, min: 25, max: 50, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.height(50)
.onChange((value: number) => {
this.rate = value / 100
})
.position({ x: '20%', y: '80%' })
}
build() {
Column() {
Column() {
Row() {
Column() {
Image($r("app.media.down"))
.width(48)
.height(48)
}
.height(96)
.layoutWeight(1) // 設(shè)置子組件在父容器主軸方向的布局權(quán)重
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
Column() {
Image($r("app.media.pause"))
.width(48)
.height(48)
}
.height(96)
.layoutWeight(1) // 設(shè)置子組件在父容器主軸方向的布局權(quán)重
.backgroundColor('#66F1CCB8')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
Column() {
Image($r("app.media.next"))
.width(48)
.height(48)
}
.height(96)
.layoutWeight(1) // 設(shè)置子組件在父容器主軸方向的布局權(quán)重
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
.width(this.rate * 100 + '%')
.height(96)
.borderRadius(16)
.backgroundColor('#FFFFFF')
}
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
縮放能力
設(shè)置aspectRatio寬高比屬性,父容器發(fā)生改變,子組件的寬高比不變。

@Entry
@Component
struct ScaleCapabilitySample {
@State sliderWidth: number = 400
@State sliderHeight: number = 400
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽? @Builder slider() {
Slider({ value: this.sliderHeight, min: 100, max: 400, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.height(50)
.onChange((value: number) => {
this.sliderHeight = value
})
.position({ x: '20%', y: '80%' })
Slider({ value: this.sliderWidth, min: 100, max: 400, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.height(50)
.onChange((value: number) => {
this.sliderWidth = value;
})
.position({ x: '20%', y: '87%' })
}
build() {
Column() {
Column() {
Column() {
Image($r("app.media.illustrator")).width('100%').height('100%')
}
.aspectRatio(1) // 固定寬高比
.border({ width: 2, color: "#66F1CCB8"}) // 邊框,僅用于展示效果
}
.backgroundColor("#FFFFFF")
.height(this.sliderHeight)
.width(this.sliderWidth)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor("#F1F3F5")
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
延伸能力
子組件隨著父容器尺寸變化顯示或者隱藏。延伸能力通常有兩種實現(xiàn)方式:
- 通過List組件。
-
通過Scroll組件配合Row組件或Column組件實現(xiàn)。
示例圖
@Entry
@Component
struct ExtensionCapabilitySample1 {
@State rate: number = 0.60
readonly appList: number [] = [0, 1, 2, 3, 4, 5, 6, 7]
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽? @Builder slider() {
Slider({ value: this.rate * 100, min: 8, max: 60, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.height(50)
.onChange((value: number) => {
this.rate = value / 100
})
.position({ x: '20%', y: '80%' })
}
build() {
Column() {
Row({ space: 10 }) {
// 通過List組件實現(xiàn)隱藏能力
List({ space: 10 }) {
ForEach(this.appList, (item:number) => {
ListItem() {
Column() {
Image($r("app.media.startIcon")).width(48).height(48).margin({ top: 8 })
Text('App name')
.width(64)
.height(30)
.lineHeight(15)
.fontSize(12)
.textAlign(TextAlign.Center)
.margin({ top: 8 })
.padding({ bottom: 15 })
}.width(80).height(102)
}.width(80).height(102)
})
}
.padding({ top: 16, left: 10 })
.listDirection(Axis.Horizontal)
.width('100%')
.height(118)
.borderRadius(16)
.backgroundColor(Color.White)
}
.width(this.rate * 100 + '%')
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
隱藏能力
給子組件設(shè)置布局優(yōu)先級(displayPriority屬性),父組件尺寸變化,按照優(yōu)先級對子組件進行顯示或者隱藏。

@Entry
@Component
struct HiddenCapabilitySample {
@State rate: number = 0.45
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽? @Builder slider() {
Slider({ value: this.rate * 100, min: 10, max: 45, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.height(50)
.onChange((value: number) => {
this.rate = value / 100
})
.position({ x: '20%', y: '80%' })
}
build() {
Column() {
Row() {
Image($r("app.media.favorite"))
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
.margin({ left: 12, right: 12 })
.displayPriority(1) // 布局優(yōu)先級
Image($r("app.media.down"))
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
.margin({ left: 12, right: 12 })
.displayPriority(2) // 布局優(yōu)先級
Image($r("app.media.pause"))
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
.margin({ left: 12, right: 12 })
.displayPriority(3) // 布局優(yōu)先級
Image($r("app.media.next"))
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
.margin({ left: 12, right: 12 })
.displayPriority(2) // 布局優(yōu)先級
Image($r("app.media.list"))
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
.margin({ left: 12, right: 12 })
.displayPriority(1) // 布局優(yōu)先級
}
.width(this.rate * 100 + '%')
.height(96)
.borderRadius(16)
.backgroundColor('#FFFFFF')
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
折行能力
折行能力通過使用 Flex折行布局 (將wrap屬性設(shè)置為FlexWrap.Wrap)實現(xiàn),當橫向布局尺寸不足以完整顯示內(nèi)容元素時,通過折行的方式,將元素顯示在下方。

@Entry
@Component
struct WrapCapabilitySample {
@State rate: number = 0.7
readonly imageList: Resource [] = [
$r('app.media.flexWrap1'),
$r('app.media.flexWrap2'),
$r('app.media.flexWrap3'),
$r('app.media.flexWrap4'),
$r('app.media.flexWrap5'),
$r('app.media.flexWrap6')
]
// 底部滑塊,可以通過拖拽滑塊改變?nèi)萜鞒叽? @Builder slider() {
Slider({ value: this.rate * 100, min: 50, max: 70, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.onChange((value: number) => {
this.rate = value / 100
})
.position({ x: '20%', y: '87%' })
}
build() {
Flex({ justifyContent: FlexAlign.Center, direction: FlexDirection.Column }) {
Column() {
// 通過Flex組件warp參數(shù)實現(xiàn)自適應(yīng)折行
Flex({
direction: FlexDirection.Row,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center,
wrap: FlexWrap.Wrap
}) {
ForEach(this.imageList, (item:Resource) => {
Image(item).width(183).height(138).padding(10)
})
}
.backgroundColor('#FFFFFF')
.padding(20)
.width(this.rate * 100 + '%')
.borderRadius(16)
}
.width('100%')
this.slider()
}.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
}
}
這就是自適應(yīng)布局的7種能力,下面給出一個案例,主要是想讓大家知道這7種能力可以用在什么地方。

上圖是一個音樂播放器,左邊是音樂播放器在平板上的顯示效果,中間是音樂播放器在手機上的顯示效果,右邊是音樂播放器在折疊屏上的顯示效果。我們把音樂播放器分為6個區(qū)域。
| 區(qū)域 | 布局能力 | 實現(xiàn)方案 |
|---|---|---|
| 1、標題欄 | 自適應(yīng)布局-拉伸能力 | 外層使用Row組件,內(nèi)層的留白組件自帶拉伸能力。 |
| 2、專輯圖片 | 自適應(yīng)布局-縮放能力 | 設(shè)置圖片aspectRatio屬性,將寬高比設(shè)置1:1。 |
| 3、收藏/下載/評論/分享 | 自適應(yīng)布局-均分能力 | justifyContent屬性設(shè)置為FlexAlign.SpaceEvenly。 |
| 4、底部播放量 | 自適應(yīng)布局-占比能力 | 設(shè)置layoutWeight屬性,將左側(cè)與右側(cè)占比為3:1。 |
| 5、收藏/播放/上一首/下一首 | 自適應(yīng)布局-隱藏能力 | 設(shè)置優(yōu)先級displayPriority屬性,平板顯示5個按鈕,折疊屏顯示3個按鈕,手機顯示一個按鈕。 |
| 6、音樂列表 | 自適應(yīng)布局-延伸能力 | 設(shè)置lanes,列表顯示1列或者兩列。 |
響應(yīng)式布局
拉伸屏幕,頁面的位置關(guān)系發(fā)生變化。自適應(yīng)布局可以保證窗口尺寸在一定范圍內(nèi)變化時,頁面的顯示是正常的。但是將窗口尺寸變化較大時(如窗口寬度從400vp變化為1000vp),僅僅依靠自適應(yīng)布局可能出現(xiàn)圖片異常放大或頁面內(nèi)容稀疏、留白過多等問題,此時就需要借助響應(yīng)式布局能力調(diào)整頁面結(jié)構(gòu)。
斷點
將窗口寬度劃分為不同的范圍(即斷點),監(jiān)聽窗口尺寸變化,當斷點改變時同步調(diào)整頁面布局。斷點支持自定義,取值范圍可以修改,下標是4個常見斷點范圍。
| 名稱 | 取值范圍 |
|---|---|
| xs(超小,智能穿戴類設(shè)備) | [0, 320) |
| sm(小,手機) | [320, 600) |
| xs(中等,折疊屏) | [600, 840) |
| xs(大,平板) | [840, +∞) |
可以根據(jù)實際需要在lg斷點后面新增xl、xxl等斷點,但注意新增斷點會同時增加設(shè)計師及開發(fā)者的工作量。
系統(tǒng)提供了多種方法,判斷應(yīng)用當前處于何種斷點,進而可以調(diào)整應(yīng)用的布局。先介紹如何通過窗口對象監(jiān)聽斷點變化。
在UIAbility的onWindowStageCreate生命周期回調(diào)中,通過窗口對象獲取啟動時的應(yīng)用窗口寬度并注冊回調(diào)函數(shù)監(jiān)聽窗口尺寸變化。將窗口尺寸的長度單位由px換算為vp后,即可基于前文中介紹的規(guī)則得到當前斷點值,此時可以使用狀態(tài)變量記錄當前的斷點值方便后續(xù)使用。
// MainAbility.ts
import window from '@ohos.window'
import display from '@ohos.display'
import UIAbility from '@ohos.app.ability.UIAbility'
export default class MainAbility extends UIAbility {
private windowObj?: window.Window
private curBp: string = ''
//...
// 根據(jù)當前窗口尺寸更新斷點
private updateBreakpoint(windowWidth: number) :void{
// 將長度的單位由px換算為vp
let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels
let newBp: string = ''
if (windowWidthVp < 320) {
newBp = 'xs'
} else if (windowWidthVp < 600) {
newBp = 'sm'
} else if (windowWidthVp < 840) {
newBp = 'md'
} else {
newBp = 'lg'
}
if (this.curBp !== newBp) {
this.curBp = newBp
// 使用狀態(tài)變量記錄當前斷點值
AppStorage.setOrCreate('currentBreakpoint', this.curBp)
}
}
onWindowStageCreate(windowStage: window.WindowStage) :void{
windowStage.getMainWindow().then((windowObj) => {
this.windowObj = windowObj
// 獲取應(yīng)用啟動時的窗口尺寸
this.updateBreakpoint(windowObj.getWindowProperties().windowRect.width)
// 注冊回調(diào)函數(shù),監(jiān)聽窗口尺寸變化
windowObj.on('windowSizeChange', (windowSize)=>{
this.updateBreakpoint(windowSize.width)
})
});
// ...
}
//...
}
在頁面中,獲取及使用當前的斷點。
@Entry
@Component
struct Index {
@StorageProp('currentBreakpoint') curBp: string = 'sm'
build() {
Flex({justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
Text(this.curBp).fontSize(50).fontWeight(FontWeight.Medium)
}
.width('100%')
.height('100%')
}
}
媒體查詢
媒體查詢提供了豐富的媒體特征監(jiān)聽能力,可以監(jiān)聽應(yīng)用顯示區(qū)域變化、橫豎屏、深淺色、設(shè)備類型等等,因此在應(yīng)用開發(fā)過程中使用的非常廣泛。下面通過通過媒體查詢,監(jiān)聽應(yīng)用窗口寬度變化,獲取當前應(yīng)用所處的斷點值。
export class BreakpointSystem {
private currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM;
// 監(jiān)聽sm的屏幕尺寸
private smListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(BreakpointConstants.RANGE_SM);
// 監(jiān)聽md的屏幕尺寸
private mdListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(BreakpointConstants.RANGE_MD);
// 監(jiān)聽lg的屏幕尺寸
private lgListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(BreakpointConstants.RANGE_LG);
private updateCurrentBreakpoint(breakpoint: string): void {
if (this.currentBreakpoint !== breakpoint) {
this.currentBreakpoint = breakpoint;
// 將斷點保存到AppStorage
AppStorage.setOrCreate<string>(BreakpointConstants.CURRENT_BREAKPOINT, this.currentBreakpoint);
}
}
private isBreakpointSM = (mediaQueryResult: mediaquery.MediaQueryResult): void => {
if (mediaQueryResult.matches) {
this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_SM);
}
}
private isBreakpointMD = (mediaQueryResult: mediaquery.MediaQueryResult): void => {
if (mediaQueryResult.matches) {
this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_MD);
}
}
private isBreakpointLG = (mediaQueryResult: mediaquery.MediaQueryResult): void => {
if (mediaQueryResult.matches) {
this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_LG);
}
}
public register(): void {
this.smListener = mediaquery.matchMediaSync(BreakpointConstants.RANGE_SM);
this.smListener.on('change', this.isBreakpointSM);
this.mdListener = mediaquery.matchMediaSync(BreakpointConstants.RANGE_MD);
this.mdListener.on('change', this.isBreakpointMD);
this.lgListener = mediaquery.matchMediaSync(BreakpointConstants.RANGE_LG);
this.lgListener.on('change', this.isBreakpointLG);
}
public unregister(): void {
this.smListener.off('change', this.isBreakpointSM);
this.mdListener.off('change', this.isBreakpointMD);
this.lgListener.off('change', this.isBreakpointLG);
}
}
在上述代碼中,我們定義不同的屏幕尺寸監(jiān)聽,通過媒體查詢mediaquery.matchMediaSync來監(jiān)聽屏幕尺寸。將監(jiān)聽到的屏幕尺寸保存AppStorage,這樣其它頁面就能通過AppStorage獲取屏幕尺寸。同時提供注冊register方法和注銷unregister方法。
@Entry
@Component
struct MediaQuerySample {
@StorageLink('currentBreakpoint') private currentBreakpoint: string = "md";
private breakpointSystem: BreakpointSystem = new BreakpointSystem()
aboutToAppear() {
this.breakpointSystem.register()
}
aboutToDisappear() {
this.breakpointSystem.unregister()
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.currentBreakpoint)
.fontSize(24)
.margin(10)
}
.width('100%')
.height('100%')
}
}
在上述代碼中,在aboutToAppear中注冊媒體查詢,在aboutToDisappear中注銷媒體查詢。由于斷點保存在AppStorage,所以可以直接使用@StorageLink裝飾器從AppStorage中取出斷點。
柵格布局
根據(jù)設(shè)備的寬度,將不同的屏幕尺寸劃分為不同數(shù)量的柵格,來實現(xiàn)屏幕的自適應(yīng)。如下圖,小尺寸的手機可以畫4個柵格,折疊屏可以畫8個柵格,平板可以畫12個柵格。一般來說,推薦按照4、8、12的比例進行柵格劃分。柵格和柵格之前有12vp的間距,如果沒有間距,柵格就會擠在一起。

span用于設(shè)置柵格的數(shù)量,offset用于設(shè)置偏移量。如下圖,手機設(shè)置4個柵格,不設(shè)置偏移量。折疊屏總共有8個柵格,設(shè)置6個柵格,偏移1個柵格,就達到了居中的效果。平板總共有12個柵格,設(shè)置8個柵格,偏移2個柵格,就達到了居中的效果。

下面的代碼就實現(xiàn)了上面所說的在不同設(shè)備上的登錄頁面。
build() {
GridRow({
/**
* columns用于指定不同設(shè)備占據(jù)的總柵格數(shù),默認情況下,總柵格數(shù)為12
* 指定手機的總柵格數(shù)為4,折疊屏總柵格數(shù)為8,平板總柵格數(shù)為12。
*/
columns:{sm: 4, md: 8, lg: 12},
// 間距
gutter: 12
}) {
// 子組件
GridCol({
// 手機占4個柵格,折疊屏占8個柵,平板占12個柵格。
span: {sm: 4, md: 6, lg: 8},
// 手機不偏移,折疊屏偏移一個柵格,平板偏移2個柵格。
offset: {sm: 0, md: 1, lg: 2}
}) {
// 登錄頁面
this.loginUI()
}
}
}
柵格組件提供了豐富的自定義能力,功能異常靈活和強大。只需要明確柵格在不同斷點下的Columns、Margin、Gutter及span等參數(shù),即可確定最終布局,無需關(guān)心具體的設(shè)備類型及設(shè)備狀態(tài)(如橫豎屏)等。以上只是簡單的介紹了下柵格布局,估計有人沒看懂,關(guān)于柵格布局的詳細文檔還請查看官方文檔。


