uniapp開發鴻蒙:Flex佈局與基礎組件實戰

引入:從Hello World到實際佈局

在上一篇文章中,我們已經完成了uniapp鴻蒙開發環境的搭建,創建了第一個項目。今天,我們將深入探討uniapp在鴻蒙平台下的頁面佈局和基礎組件使用,這是構建應用界面的核心基礎。

uniapp的佈局方式與鴻蒙原生語言ArkTs有所不同,但設計理念相似。所有佈局方式都可以歸納為三種基本類型:橫向、豎向和層疊,其他複雜佈局都由這三種衍生而來。在uniapp中,我們主要通過view容器配合Flex佈局來實現各種界面效果。

一、Flex佈局基礎

1.1 橫向佈局

橫向佈局是最常用的佈局方式之一,通過設置flex-direction: row實現:

<view style="display: flex; flex-direction: row;">
  <view style="width: 100px; height: 100px; background-color: aqua;">組件1</view>
  <view style="width: 100px; height: 100px; background-color: bisque;">組件2</view>
</view>

1.2 縱向佈局

縱向佈局只需將flex-direction改為column

<view style="display: flex; flex-direction: column;">
  <view style="width: 100px; height: 100px; background-color: aqua;">組件1</view>
  <view style="width: 100px; height: 100px; background-color: bisque;">組件2</view>
</view>

1.3 層疊佈局

uniapp沒有直接提供類似ArkTs中Stack()的層疊佈局容器,但可以通過position屬性實現:

<view style="display: flex; flex-direction: column; position: relative;">
  <view style="width: 100px; height: 100px; background-color: aqua; position: absolute; top: 0;">組件1</view>
  <view style="width: 50px; height: 50px; background-color: bisque; position: absolute; z-index: 10; top: 0;">組件2</view>
</view>

關鍵點

  • 父容器需要設置position: relative
  • 子元素使用position: absolute進行絕對定位
  • 通過topleftrightbottom控制位置
  • 使用z-index控制層級關係

二、常用基礎組件

2.1 view容器組件

view是uniapp中最基礎的容器組件,相當於HTML中的div:

<view class="container">
  <view class="header">頭部</view>
  <view class="content">內容區域</view>
  <view class="footer">底部</view>
</view>

2.2 text文本組件

text用於顯示文本內容,支持豐富的樣式設置:

<text style="font-size: 28rpx; color: #333; font-weight: bold;">這是一段文本</text>

2.3 image圖片組件

image組件用於顯示圖片,支持多種加載模式:

<image src="/static/logo.png" mode="aspectFit" style="width: 200rpx; height: 200rpx;"></image>

mode屬性説明

  • aspectFit:保持寬高比縮放,使圖片的長邊能完全顯示出來
  • aspectFill:保持寬高比縮放,使圖片的短邊能完全顯示出來
  • widthFix:寬度不變,高度自動變化,保持原圖寬高比不變
  • heightFix:高度不變,寬度自動變化,保持原圖寬高比不變

2.4 button按鈕組件

button用於觸發操作,支持多種樣式和事件:

<button type="primary" size="default" @click="handleClick">點擊按鈕</button>

常用屬性

  • type:按鈕類型,可選值:default、primary、warn
  • size:按鈕尺寸,可選值:default、mini
  • disabled:是否禁用
  • loading:是否顯示加載中狀態

三、rpx單位與響應式適配

3.1 rpx單位介紹

rpx(responsive pixel)是uniapp推薦的響應式單位,1rpx等於屏幕寬度的1/750。在不同設備上,rpx會自動轉換為對應的像素值,實現自適應佈局。

使用示例

.box {
  width: 750rpx;  /* 在750設計稿中,750rpx等於屏幕寬度 */
  height: 200rpx;
  font-size: 28rpx;
}

3.2 條件編譯處理平台差異

uniapp支持條件編譯,可以根據不同平台編寫特定的樣式代碼:

/* 通用樣式 */
.box {
  width: 100%;
  height: 200rpx;
}

/* 針對鴻蒙平台的樣式 */
/* #ifdef HARMONYOS */
.box {
  background-color: #007AFF;
}
/* #endif */

/* 針對H5平台的樣式 */
/* #ifdef H5 */
.box {
  background-color: #FF9500;
}
/* #endif */

條件編譯語法

  • #ifdef:如果定義了某個平台,則編譯
  • #ifndef:如果沒有定義某個平台,則編譯
  • #endif:結束條件編譯

四、實戰案例:構建首頁佈局

4.1 頁面結構設計

下面是一個典型的首頁佈局結構:

<template>
  <view class="page">
    <!-- 頭部導航欄 -->
    <view class="header">
      <text class="title">應用名稱</text>
    </view>
    
    <!-- 內容區域 -->
    <view class="content">
      <!-- 輪播圖 -->
      <swiper class="banner" indicator-dots="true" autoplay="true" interval="3000">
        <swiper-item>
          <image src="/static/banner1.jpg" mode="aspectFill"></image>
        </swiper-item>
        <swiper-item>
          <image src="/static/banner2.jpg" mode="aspectFill"></image>
        </swiper-item>
      </swiper>
      
      <!-- 功能導航 -->
      <view class="nav">
        <view class="nav-item" v-for="item in navList" :key="item.id">
          <image :src="item.icon" class="nav-icon"></image>
          <text class="nav-text">{{item.name}}</text>
        </view>
      </view>
      
      <!-- 商品列表 -->
      <view class="product-list">
        <view class="product-item" v-for="product in productList" :key="product.id">
          <image :src="product.image" class="product-image"></image>
          <view class="product-info">
            <text class="product-name">{{product.name}}</text>
            <text class="product-price">¥{{product.price}}</text>
          </view>
        </view>
      </view>
    </view>
    
    <!-- 底部標籤欄 -->
    <view class="tabbar">
      <view class="tabbar-item" v-for="tab in tabbarList" :key="tab.id">
        <image :src="tab.icon" class="tabbar-icon"></image>
        <text class="tabbar-text">{{tab.name}}</text>
      </view>
    </view>
  </view>
</template>

4.2 樣式實現

.page {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.header {
  height: 88rpx;
  background-color: #FFFFFF;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1rpx solid #EEEEEE;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  color: #333333;
}

.content {
  flex: 1;
  overflow-y: auto;
}

.banner {
  height: 300rpx;
}

.banner image {
  width: 100%;
  height: 100%;
}

.nav {
  display: flex;
  flex-wrap: wrap;
  padding: 30rpx;
  background-color: #FFFFFF;
  margin-top: 20rpx;
}

.nav-item {
  width: 25%;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 20rpx;
}

.nav-icon {
  width: 80rpx;
  height: 80rpx;
}

.nav-text {
  font-size: 24rpx;
  color: #666666;
  margin-top: 10rpx;
}

.product-list {
  padding: 20rpx;
}

.product-item {
  display: flex;
  margin-bottom: 20rpx;
  background-color: #FFFFFF;
  border-radius: 10rpx;
  overflow: hidden;
}

.product-image {
  width: 200rpx;
  height: 200rpx;
}

.product-info {
  flex: 1;
  padding: 20rpx;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.product-name {
  font-size: 28rpx;
  color: #333333;
}

.product-price {
  font-size: 32rpx;
  color: #FF6B00;
  font-weight: bold;
}

.tabbar {
  height: 100rpx;
  background-color: #FFFFFF;
  display: flex;
  border-top: 1rpx solid #EEEEEE;
}

.tabbar-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.tabbar-icon {
  width: 44rpx;
  height: 44rpx;
}

.tabbar-text {
  font-size: 20rpx;
  color: #666666;
  margin-top: 6rpx;
}

4.3 數據綁定

export default {
  data() {
    return {
      navList: [
        { id: 1, name: '首頁', icon: '/static/nav-home.png' },
        { id: 2, name: '分類', icon: '/static/nav-category.png' },
        { id: 3, name: '購物車', icon: '/static/nav-cart.png' },
        { id: 4, name: '我的', icon: '/static/nav-mine.png' }
      ],
      productList: [
        { id: 1, name: '商品名稱1', price: 99.9, image: '/static/product1.jpg' },
        { id: 2, name: '商品名稱2', price: 199.9, image: '/static/product2.jpg' },
        { id: 3, name: '商品名稱3', price: 299.9, image: '/static/product3.jpg' }
      ],
      tabbarList: [
        { id: 1, name: '首頁', icon: '/static/tab-home.png' },
        { id: 2, name: '分類', icon: '/static/tab-category.png' },
        { id: 3, name: '購物車', icon: '/static/tab-cart.png' },
        { id: 4, name: '我的', icon: '/static/tab-mine.png' }
      ]
    }
  }
}

五、佈局技巧與最佳實踐

5.1 Flex佈局常用屬性

主軸對齊方式

.container {
  justify-content: flex-start;    /* 左對齊 */
  justify-content: center;         /* 居中對齊 */
  justify-content: flex-end;        /* 右對齊 */
  justify-content: space-between;   /* 兩端對齊,項目間間隔相等 */
  justify-content: space-around;   /* 每個項目兩側的間隔相等 */
}

交叉軸對齊方式

.container {
  align-items: flex-start;         /* 頂部對齊 */
  align-items: center;            /* 居中對齊 */
  align-items: flex-end;          /* 底部對齊 */
  align-items: stretch;           /* 拉伸填滿容器高度 */
}

5.2 響應式佈局處理

使用媒體查詢

@media screen and (max-width: 750px) {
  .nav-item {
    width: 50%;
  }
}

@media screen and (min-width: 751px) {
  .nav-item {
    width: 25%;
  }
}

使用rpx適配

/* 在750設計稿中,750rpx等於屏幕寬度 */
.container {
  width: 750rpx;
  padding: 30rpx;
}

/* 在375設計稿中,375rpx等於屏幕寬度 */
.container {
  width: 375rpx;
  padding: 15rpx;
}

5.3 性能優化建議

  1. 避免過度嵌套:減少view容器的嵌套層級,提高渲染性能
  2. 使用條件編譯:針對不同平台編寫特定代碼,避免不必要的代碼執行
  3. 圖片優化:使用合適的圖片格式和尺寸,減少資源加載時間
  4. 樣式複用:提取公共樣式,減少代碼冗餘

總結

通過本篇文章的學習,我們掌握了uniapp在鴻蒙平台下的Flex佈局和基礎組件的使用方法。關鍵知識點包括:

  1. Flex佈局:橫向、縱向、層疊三種基本佈局方式
  2. 基礎組件:view、text、image、button等常用組件
  3. rpx單位:響應式佈局的核心單位
  4. 條件編譯:處理多平台差異的有效方法
  5. 實戰案例:構建完整的首頁佈局

在實際開發中,建議多使用Flex佈局,配合rpx單位實現響應式設計,同時通過條件編譯處理平台差異。下一篇文章,我們將深入講解頁面路由與導航,實現多頁面應用的跳轉和數據傳遞。