HarmonyOS鸿蒙Next中请教下如何在首页切换到某个tab刷新下数据

HarmonyOS鸿蒙Next中请教下如何在首页切换到某个tab刷新下数据 如下我写的主界面代码,我怎么实现在点击到第二个tab的时候,刷新下第二个tab界面的数据??

用什么方法,用的最新版本开发工具,百度用什么@Watch(‘refreshKey’) 找到不到这方法

如下是主界面代码

@Entry
@Component
struct Index {

  @Provide('pageIndex') pageIndex: NavPathStack = new NavPathStack()

  @State currentIndex: number = 0;

  @State menus: MenuItemType[] = [
    { icon: 'svg_home', text: '首页'},
    { icon: 'svg_find', text: '教程' },
    { icon: 'svg_collect', text: '收藏' },
    { icon: 'svg_me', text: '我的' },
  ]

  @Builder
  tabBuilderBar(item: MenuItemType, index: number) {
    Column({ space: 4 }) {
      Image($r(`app.media.${item.icon}`))
        .width(25)
        .fillColor(index === this.currentIndex ? $r('app.color.color_load') : '#808182')
      Text(item.text)
        .fontSize(12)
        .fontColor(index === this.currentIndex ? $r('app.color.color_load') : '#808182')
    }
  }

  @Builder
  tabBuilderContent(index: number) {
    if (index === 0) { //  首页界面
      HomeIndex()
    } else if (index === 1) { // 发现界面
     FindIndex()
    } else if (index === 2) { // 我的收藏
      CollectIndex()
    }else if (index ===3) { // 个人信息界面
      MeIndex()
    }
  }

  build() {
    Navigation(this.pageIndex) {
      Column() {
        Tabs({ barPosition: BarPosition.End, index: this.currentIndex }) {
          ForEach(this.menus, (item: MenuItemType, index: number) => {
            TabContent() {
              this.tabBuilderContent(index)
            }
            .tabBar(this.tabBuilderBar(item, index))
          })
        }
        .scrollable(false) // 制滑动切换
        .animationDuration(0)
        .barBackgroundColor($r('app.color.main_bg'))
        .onChange((index: number) => {
          this.currentIndex = index
        })
        .divider({
          strokeWidth: 1,
          color: '#ffeaeaea'
        })
       }
       .width('100%')
       .height('100%')
    }
    .hideToolBar(true)
    .width('100%')
    .height('100%')
  }
}

我想每次点击到我的收藏界面,然后我的收藏界面会刷新下数据 用什么好实现


更多关于HarmonyOS鸿蒙Next中请教下如何在首页切换到某个tab刷新下数据的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

如果想精准控制在切换到 CollectIndex 页面时刷新数据, 可以传一个 controller 给收藏页面,由它去实现刷新逻辑。 在页面切换时,调用 controller 的刷新方法。

大致代码如下:

@Entry
@Component
struct Index {
  collectController: CollectController = new CollectController()

  @Builder
  tabBuilderContent(index: number) {
    if (index === 0) { //  首页界面
      HomeIndex()
    } else if (index === 1) { // 发现界面
      FindIndex()
    } else if (index === 2) { // 我的收藏
      CollectIndex({ controller: this.collectController })
    } else if (index === 3) { // 个人信息界面
      MeIndex()
    }
  }

  build() {
    Tabs({ barPosition: BarPosition.End, index: this.currentIndex }) {

    }
    .onChange((index: number) => {
      this.currentIndex = index
      if (index === 2) {
        this.collectController.onRefresh?.()
      }
    })
  }
}

class CollectController {
  onRefresh?: () => void
}

@Component
export struct CollectIndex {
  // 外部传进来
  controller: CollectController = new CollectController()

  aboutToAppear(): void {
    this.controller.onRefresh = () => {
      //在这里请求你的接口
    }
  }

  build() {
    //你的UI
  }
}

更多关于HarmonyOS鸿蒙Next中请教下如何在首页切换到某个tab刷新下数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


可以在切换回调onChange里面刷新

参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-tabs#onchange

@Entry
@Component
struct Index {

  @Provide('pageIndex') pageIndex: NavPathStack = new NavPathStack()

  @State currentIndex: number = 0;

  @State menus: MenuItemType[] = [
    { icon: 'svg_home', text: '首页'},
    { icon: 'svg_find', text: '教程' },
    { icon: 'svg_collect', text: '收藏' },
    { icon: 'svg_me', text: '我的' },
  ]

  @Builder
  tabBuilderBar(item: MenuItemType, index: number) {
    Column({ space: 4 }) {
      Image($r(`app.media.${item.icon}`))
        .width(25)
        .fillColor(index === this.currentIndex ? $r('app.color.color_load') : '#808182')
      Text(item.text)
        .fontSize(12)
        .fontColor(index === this.currentIndex ? $r('app.color.color_load') : '#808182')
    }
  }

  @Builder
  tabBuilderContent(index: number) {
    if (index === 0) { //  首页界面
      HomeIndex()
    } else if (index === 1) { // 发现界面
     FindIndex()
    } else if (index === 2) { // 我的收藏
      CollectIndex()
    }else if (index ===3) { // 个人信息界面
      MeIndex()
    }
  }

  build() {
    Navigation(this.pageIndex) {
      Column() {
        Tabs({ barPosition: BarPosition.End, index: this.currentIndex }) {
          ForEach(this.menus, (item: MenuItemType, index: number) => {
            TabContent() {
              this.tabBuilderContent(index)
            }
            .tabBar(this.tabBuilderBar(item, index))
          })
        }
        .scrollable(false) // 制滑动切换
        .animationDuration(0)
        .barBackgroundColor($r('app.color.main_bg'))
        .onChange((index: number) => {
          //在这里执行刷新逻辑
          this.currentIndex = index
        })
        .divider({
          strokeWidth: 1,
          color: '#ffeaeaea'
        })
       }
       .width('100%')
       .height('100%')
    }
    .hideToolBar(true)
    .width('100%')
    .height('100%')
  }
}

使用页面生命周期控制方案

TabContent() {
  Index()
    .onWillShow(() => {
      this.loadNewsData() // 每次Tab显示时加载数据
    })
}

使用生命周期钩子函数应该可以,在CollectIndex页面组件中实现aboutToAppear生命周期:

@Component
struct CollectIndex {
  aboutToAppear() {
    this.loadData() // 每次进入页面时自动执行数据刷新
  }
  private loadData() {
    // 这里执行数据获取逻辑
  }
}

或者也可以通过Tabs切换事件触发

@State refreshKey: number = 0

Tabs({
  // 原有配置
})
.onChange((index: number) => {
  if (index === 2) { // 收藏页面对应的索引
    this.refreshKey += 1 // 触发状态变化
  }
})

// 收藏页面组件
@Component
struct CollectIndex {
  @Link refreshKey: number
  
  aboutToAppear() {
    this.loadData()
  }
  @Watch('refreshKey')
  watchRefresh() {
    this.loadData()
  }
}
@State @Watch('currentIndexChange') currentIndex: number = 0;
@Provide @Watch('quickChange') priceObj: PriceKey | null = null;
@Provide @Watch('quickChange') modelObj: ModelKey | null = null;
@Provide @Watch('quickChange') brandObj: BrandKey | null = null;
@Link currentIndex: number;

可以看下xue’t视频教程

楼主你好,这个问题可以通过Emitter事件通知来实现,具体实现如下:

  • Emitter主要提供线程间发送和处理事件的能力,包括对持续订阅事件或单次订阅事件的处理、取消订阅事件、发送事件到事件队列等。工作原理是使用emitter.emit发送指定事件,再通过emitter.on持续订阅指定的事件,并在接收到该事件时,执行对应的回调处理函数。

在主页面通过emitter.emit(‘refreshTable’)发送指定的事件refreshTable,参考代码如下:

import { SubTabContent } from './SubTabContent'
import { emitter } from '@kit.BasicServicesKit'

@Entry
@Component
struct TabContentExample {
  @State fontColor: string = '#182431'
  @State selectedFontColor: string = '#007DFF'
  @State currentIndex: number = 0
  @State selectedIndex: number = 0
  @State refreshFlag: boolean = true
  private controller: TabsController = new TabsController()

  @Builder
  tabBuilder(index: number) {
    Column() {
      Text(`Tab${index + 1}`)
        .fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
        .fontSize(20)
        .fontWeight(500)
        .lineHeight(14)
    }.width('100%')
  }

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
        TabContent() {
          Column() {
            SubTabContent()
          }
          .width('100%')
        }.tabBar(this.tabBuilder(0))

        TabContent() {
          Column() {
            Text('Tab2')
              .fontSize(36)
              .fontColor('#182431')
              .fontWeight(500)
              .opacity(0.4)
              .margin({ top: 30, bottom: 56.5 })
            Divider()
              .strokeWidth(0.5)
              .color('#182431')
              .opacity(0.05)
          }.width('100%')
        }.tabBar(this.tabBuilder(1))
      }
      .vertical(false)
      .barHeight(56)
      .onChange((index: number) => {
        this.currentIndex = index
        this.selectedIndex = index
        if (index === 0) {
          // 事件携带的数据
          let eventData: emitter.EventData = {
            data: {}
          };
          // 通过emitter.emit('refreshTable')发送指定的事件
          emitter.emit("refreshTable", eventData);
        }
      })
      .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
        if (index === targetIndex) {
          return
        }
        // selectedIndex控制自定义TabBar内Image和Text颜色切换
        this.selectedIndex = targetIndex
      })
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')
      .margin({ top: 38 })
    }
    .width('100%')
    .height('100%')
    .padding({
      bottom: 30
    })
  }
}

在子页面通过emitter.on(‘refreshTable’)持续订阅该事件去刷新数据,参考代码如下:

import { emitter } from '@kit.BasicServicesKit';

@Component
export struct SubTabContent {
  @State counter: number = 0

  aboutToAppear(): void {
    // Tabs子组件通过emitter.on('refreshTable')持续订阅该事件去刷新数据
    emitter.on("refreshTable", () => {
      this.counter += 1
    });
  }

  build() {
    Text(`切换Tabs刷新数据${this.counter}`)
  }
}

问:如果子页面的数据是从服务器拉取的要怎么做?

答:在子页面的事件监听回调里调用数据拉取接口,处理从服务器请求的数据,再去刷新子页面。

在HarmonyOS Next中,要在首页切换到某个Tab时刷新数据,可以使用TabContent组件的onChange事件监听Tab切换。在事件回调中,调用数据刷新方法。例如,在TabContentonChange事件中,判断切换到的Tab索引,执行对应的数据加载或刷新逻辑。

在HarmonyOS Next中,要实现切换到特定Tab时刷新数据,可以通过监听currentIndex的变化来实现。以下是几种解决方案:

方案一:使用onChange监听索引变化

修改Tabs的onChange回调,在索引变化时触发数据刷新:

.onChange((index: number) => {
  this.currentIndex = index
  // 当切换到第二个tab(索引为1)时刷新数据
  if (index === 1) {
    // 这里可以调用FindIndex组件的刷新方法
    // 或者通过状态管理触发刷新
  }
})

方案二:在子组件中监听currentIndex变化

在FindIndex组件中,通过@Link@Prop接收currentIndex,并监听其变化:

// FindIndex组件
@Component
struct FindIndex {
  [@Link](/user/Link) currentIndex: number
  @State data: any[] = []
  
  aboutToAppear() {
    this.loadData()
  }
  
  loadData() {
    // 加载数据的逻辑
  }
  
  build() {
    // 组件内容
  }
}

然后在父组件中传递currentIndex:

// 修改tabBuilderContent方法
@Builder
tabBuilderContent(index: number) {
  if (index === 1) {
    FindIndex({ currentIndex: $currentIndex })
  }
  // ... 其他tab
}

方案三:使用自定义事件或状态管理

  1. 定义刷新状态
@State refreshKey: number = 0
  1. 在onChange中更新
.onChange((index: number) => {
  this.currentIndex = index
  if (index === 1) {
    this.refreshKey += 1  // 触发刷新
  }
})
  1. 在FindIndex组件中监听
@Component
struct FindIndex {
  [@Prop](/user/Prop) refreshKey: number
  
  aboutToAppear() {
    this.loadData()
  }
  
  onRefreshKeyChange() {
    this.loadData()
  }
  
  loadData() {
    // 刷新数据
  }
}

方案四:使用Tabs的onTabChange事件(如果API支持)

检查最新文档,看是否有更直接的Tab切换事件。

推荐实现

对于你的场景,建议使用方案三,因为它:

  1. 明确控制刷新时机
  2. 避免不必要的重复刷新
  3. 代码结构清晰

在FindIndex组件中,可以通过aboutToAppear生命周期加载初始数据,再通过监听refreshKey的变化来触发后续刷新。

注意:HarmonyOS Next的API可能会有更新,建议查阅最新官方文档确认最佳实践。

回到顶部