鸿蒙开发 bindSheet 的详细使用

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、bindSheet 核心功能

bindSheet 是鸿蒙中用于 底部弹窗(Bottom Sheet)数据绑定 的关键方法,通常与 @State@Link 装饰器配合使用,实现动态内容更新。主要应用于:

  • 动态列表渲染
  • 表单数据绑定
  • 交互式弹窗内容更新

二、基础用法

1. 基本结构定义
@Entry
@Component
struct BindSheetExample {
  @State sheetData: string[] = ['选项A', '选项B', '选项C'];
  @State isShowSheet: boolean = false;

  build() {
    Column() {
      Button('打开底部弹窗')
        .onClick(() => {
          this.isShowSheet = true;
        })
    }
    .bindSheet(
      this.isShowSheet, // 控制显示/隐藏
      this.sheetData,   // 绑定数据源
      (item: string) => {
        // 渲染每一项
        Text(item)
          .fontSize(16)
          .margin(10)
      }
    )
  }
}
2. 参数说明
参数 类型 必填 说明
isShow boolean 控制弹窗显示/隐藏
data Array 数据源数组
itemBuilder (item: any) => void 每一项的UI构建函数

三、高级用法

1. 动态数据更新
@State sheetData: { id: number, name: string }[] = [
  { id: 1, name: '苹果' },
  { id: 2, name: '香蕉' }
];

// 点击添加新项
addItem() {
  this.sheetData.push({ id: Date.now(), name: '新水果' });
  this.sheetData = [...this.sheetData]; // 必须更新引用触发刷新
}

build() {
  Column() {
    Button('添加选项')
      .onClick(() => this.addItem())
  }
  .bindSheet(
    this.isShowSheet,
    this.sheetData,
    (item) => {
      Text(`${item.id}. ${item.name}`)
        .onClick(() => {
          console.log(`选择了: ${item.name}`);
          this.isShowSheet = false;
        })
    }
  )
}
2. 自定义弹窗样式
.bindSheet(
  this.isShowSheet,
  this.sheetData,
  (item) => Text(item),
  {
    backgroundColor: '#F5F5F5', // 背景色
    height: '50%',              // 弹窗高度
    borderRadius: 20,           // 圆角
    dragBar: true               // 显示拖动条
  }
)
3. 事件监听
.bindSheet(
  this.isShowSheet,
  this.sheetData,
  (item) => Text(item),
  {
    onAppear: () => console.log('弹窗打开'),
    onDisappear: () => console.log('弹窗关闭'),
    onDismiss: (reason: SheetDismissReason) => {
      // 处理关闭原因(点击背景/拖动关闭等)
      console.log(`关闭原因: ${reason}`);
    }
  }
)

四、案例:多功能选择器

@Entry
@Component
struct MultiSelectSheet {
  @State isShow: boolean = false;
  @State selectedItems: string[] = [];
  @State allItems: string[] = ['红色', '绿色', '蓝色', '黄色'];

  toggleSelect(item: string) {
    if (this.selectedItems.includes(item)) {
      this.selectedItems = this.selectedItems.filter(i => i !== item);
    } else {
      this.selectedItems = [...this.selectedItems, item];
    }
  }

  build() {
    Column() {
      Text(`已选: ${this.selectedItems.join(',')}`)
        .margin(10)
      
      Button('选择颜色')
        .onClick(() => this.isShow = true)
    }
    .bindSheet(
      this.isShow,
      this.allItems,
      (item) => {
        Row() {
          Text(item)
            .fontSize(18)
          
          if (this.selectedItems.includes(item)) {
            Image($r('app.media.checked'))
              .width(20)
              .margin(10)
          }
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        .onClick(() => this.toggleSelect(item))
      },
      {
        height: '60%',
        onDismiss: () => {
          console.log('最终选择:', this.selectedItems);
        }
      }
    )
  }
}

五、性能优化技巧

1. 数据分页加载
@State currentPage: number = 1;
@State loadedData: string[] = [];

loadMore() {
  // 模拟分页请求
  const newData = /* 网络请求获取数据 */;
  this.loadedData = [...this.loadedData, ...newData];
}

.bindSheet(
  this.isShowSheet,
  this.loadedData,
  (item) => Text(item),
  {
    onReachEnd: () => {
      this.currentPage++;
      this.loadMore();
    }
  }
)
2. 复用组件
// 定义可复用项组件
@Component
struct SheetItem {
  @Prop item: string;

  build() {
    Text(this.item)
      .fontSize(16)
      .backgroundColor('#EEE')
      .margin(5)
  }
}

// 在bindSheet中使用
.bindSheet(
  this.isShowSheet,
  this.sheetData,
  (item) => {
    SheetItem({ item })
  }
)

六、API 参数说明

参数 类型 默认值 说明
isShow boolean false 控制显示/隐藏
data Array [] 数据源数组
itemBuilder (item: any) => void - 每项渲染函数
options SheetOptions {} 可选配置项

SheetOptions 配置项

interface SheetOptions {
  height?: Length;                   // 弹窗高度
  backgroundColor?: ResourceColor;  // 背景色
  dragBar?: boolean;                 // 是否显示拖动条
  onAppear?: () => void;            // 打开回调
  onDisappear?: () => void;         // 关闭回调
  onDismiss?: (reason: SheetDismissReason) => void; // 关闭原因回调
}

 

你可能感兴趣的:(鸿蒙,harmonyos,华为,鸿蒙,bindSheet)