前言

上一篇文章讲解了不同页面之间的路由跳转,这次详细的说明一下路由跳转中的参数传递。在日常开发中有着这样的一种情况,多个相同的页面展示着不同的内容。这种情况就可以使用路由跳转中的参数传递,来使一个页面根据不同数据来展示不同的页面。

参数传递和接收

在跳转页面的地方加上params可以实现参数的传递,参数是以对象的形式传递的。然后在接受页面使用router的getParams方法来获取传递的参数。

// -----------传递参数------------
// 普通跳转 并 传递参数
router.pushUrl({
  url:'地址',
  params:{
    // 以对象的形式传递参数
  }
})
// 覆盖跳转并传递参数
router.replaceUrl(
  url:'地址',
  params:{
    // 以对象的形式传递参数
  }
)

// -------------页面 B接收并解析参数------------
// aboutToAppear一会展开 (生命周期函数)
aboutToAppear(): void {
  // 1.确认内容
  console.log(JSON.stringify(router.getParams())) 
  // 2.通过 as 类型断言 转为具体的类型
  const params =  router.getParams() as 类型
  // 3. 通过点语法即可取值
  params.xxx 
} 

小案例

在ets文件夹下创建一个data文件夹用来存放数据,然后创建一个名为XCF的文件夹用来存放页面。


首先是Home页面:

import { Category, CategoryContainer } from '../../data/CategoryData'
import { router } from '@kit.ArkUI'


@Entry
@Component
struct XCFDemo {
  @State list: CategoryContainer[] = CategoryContainer.getCategoryContainerList()

  build() {
    Column() {
      // 顶部
      TopCom()
      // 内容
      ContentCom({ list: this.list })
        .layoutWeight(1)
      // 底部
      BottomCom()

    }
    .width('100%')
    .height('100%')
  }
}

// 顶部组件:图片代替
@Component
struct TopCom {
  build() {
    Image($r('app.media.ic_public_XCF_TOP'))
      .width('100%')
  }
}

// 内容组件:渲染列表
@Component
struct ContentCom {
  @Prop list: CategoryContainer[]

  build() {
    Scroll() {
      Column({ space: 30 }) {
        ForEach(this.list, (item: CategoryContainer) => {
          Column({ space: 15 }) {
            Text(item.title)
              .fontSize(20)
              .alignSelf(ItemAlign.Start)
              .fontWeight(FontWeight.Medium)
            Grid() {
              ForEach(item.categorizes, (cateItem: Category) => {
                GridItem() {
                  Stack({ alignContent: Alignment.Bottom }) {
                    Image(cateItem.cover)
                    Text(cateItem.title)
                      .fontColor(Color.White)
                      .fontSize(14)
                      .padding({ bottom: 10 })
                  }
                  .borderRadius(10)
                  .clip(true)
                  .onClick(() => {
                    //跳转页面的同时传递数据。
                    router.pushUrl({
                      url: 'pages/XCF/XCFDetailPage',
                      //要使用里面的id和标题,所以可以传整个cateitem。
                      params: cateItem

                    })
                  })

                }
              })
            }
            .columnsTemplate('1fr 1fr 1fr')
            .columnsGap(10)
            .rowsGap(10)
          }
          .height(240)
        })
      }
      .padding(20)
    }
    .scrollBar(BarState.Off)
    .edgeEffect(EdgeEffect.Spring)

  }
}

// 底部组件:图片代替
@Component
struct BottomCom {
  build() {
    Image($r('app.media.ic_public_XCF_Bottom'))
      .width('100%')

  }
}

然后是Detail页面

import { Food, FoodList } from '../../data/FoodData';
import { router } from '@kit.ArkUI';
import { Category, } from '../../data/CategoryData'

@Entry
@Component
struct CategoryPage {
  // 渲染食物列表
  foods: Food[] = []
  @State item: Category = {} as Category

  aboutToAppear(): void {
    // 接收路由传递而来的数据
    this.item = router.getParams() as Category
    //筛选数据
    this.foods = FoodList.filter(ele => ele.categoryId === this.item.id)
  }

  build() {
    Column() {
      // 顶部
      //展示分类里面第一个菜品的图片
      TopCom({ cover: this.foods[0].cover, title: this.item.title })

      // 列表
      List({ space: 20 }) {
        ForEach(this.foods, (food: Food) => {
          ListItem() {
            Row() {
              Image(food.cover)
                .width(150)
                .height(110)
                .borderRadius(10)
              Column() {
                Text(food.title)
                Text() {
                  Span(`评分:${food.score}    `)
                  Span(`${food.count} 人做过`)
                }
                .fontSize(12)

                Row({ space: 10 }) {
                  // 作者头像
                  Image(food.author.avatar)
                    .width(20)
                    .height(20)
                    .borderRadius(10)
                  // 作者昵称
                  Text(food.author.nickname)
                    .fontSize(10)
                    .fontColor(Color.Gray)
                }
              }
              .alignItems(HorizontalAlign.Start)
              .justifyContent(FlexAlign.SpaceBetween)
              .layoutWeight(1)
              .padding({ top: 5, bottom: 5, left: 10 })
              .height(110)
            }
          }
        })
      }
      .padding(20)
      .layoutWeight(1)
    }
    .height('100%')
  }
}

@Component
struct TopCom {
  @Prop cover: string
  @Prop title: string

  build() {
    Stack() {
      // 顶部封面
      Image(this.cover)
        .height('100%')
        .width('100%')
      Column() {
        // 返回按钮
        Image($r('app.media.ic_public_arrow_left'))
          .fillColor(Color.White)
          .width(30)
          .onClick(() => {
            router.back()
          })

        // 顶部标题
        Text(this.title)
          .fontColor(Color.White)
          .fontSize(30)
      }
      .justifyContent(FlexAlign.SpaceAround)
      .alignItems(HorizontalAlign.Start)
      .padding(20)
      .backgroundColor('rgba(0,0,0,0.4)')
      .width('100%')
      .height('100%')
    }
    .height(220)
  }
}

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐