【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染

【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染

一、环境说明

  1. DevEco Studio 版本:
    在这里插入图片描述

  2. API版本:以12为主
    在这里插入图片描述

二、调用后台接口及List组件渲染

  1. 后台接口及返回数据分析
    在这里插入图片描述
    JSON数据格式如下:

    {
        "code": 0,
        "data": {
            "total": 6,
            "pageSize": 10,
            "totalPage": 1,
            "currPage": 1,
            "list": [
                {
                    "id": 31,
                    "biaoti": "标题1",
                    "neirong": "内容1",
                    "shipin": "",
                    "fabushijian": "2024-08-05 11:59:42",
                    "faburen": "发布人1",
                    "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian1.jpg",
                    "thumbsupnum": 1,
                    "crazilynum": 1,
                    "clicktime": "2024-08-05 12:00:04",
                    "clicknum": 4,
                    "addtime": "2024-08-05 11:59:29"
                },
                {
                    "id": 32,
                    "biaoti": "标题2",
                    "neirong": "内容2",
                    "shipin": "",
                    "fabushijian": "2024-08-05 11:59:42",
                    "faburen": "发布人2",
                    "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian2.jpg",
                    "thumbsupnum": 2,
                    "crazilynum": 2,
                    "clicktime": "2024-08-05 12:00:04",
                    "clicknum": 5,
                    "addtime": "2024-08-05 11:59:29"
                },
                {
                    "id": 33,
                    "biaoti": "标题3",
                    "neirong": "内容3",
                    "shipin": "",
                    "fabushijian": "2024-08-05 11:59:42",
                    "faburen": "发布人3",
                    "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian3.jpg",
                    "thumbsupnum": 3,
                    "crazilynum": 3,
                    "clicktime": "2024-08-05 12:00:04",
                    "clicknum": 3,
                    "addtime": "2024-08-05 11:59:29"
                },
                {
                    "id": 34,
                    "biaoti": "标题4",
                    "neirong": "内容4",
                    "shipin": "",
                    "fabushijian": "2024-08-05 11:59:42",
                    "faburen": "发布人4",
                    "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian4.jpg",
                    "thumbsupnum": 4,
                    "crazilynum": 4,
                    "clicktime": "2024-08-05 12:01:05",
                    "clicknum": 7,
                    "addtime": "2024-08-05 11:59:29"
                },
                {
                    "id": 35,
                    "biaoti": "标题5",
                    "neirong": "内容5",
                    "shipin": "",
                    "fabushijian": "2024-08-05 11:59:42",
                    "faburen": "发布人5",
                    "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian5.jpg",
                    "thumbsupnum": 5,
                    "crazilynum": 5,
                    "clicktime": "2024-08-05 12:00:04",
                    "clicknum": 5,
                    "addtime": "2024-08-05 11:59:29"
                },
                {
                    "id": 36,
                    "biaoti": "标题6",
                    "neirong": "<p>66232</p>",
                    "shipin": "",
                    "fabushijian": "2024-08-05 11:59:42",
                    "faburen": "发布人6",
                    "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian6.jpg",
                    "thumbsupnum": 6,
                    "crazilynum": 6,
                    "clicktime": "2024-08-05 12:00:50",
                    "clicknum": 12,
                    "addtime": "2024-08-05 11:59:29"
                }
            ]
        }
    }
    
  2. 新建后台数据相关的实体类
    新建common目录并在其下新建bean目录,然后在bean目录下新建NewsDataItem.ets类,用于封装整个后台JSON数据的最内层数据

    /**
     * 用于定义具体的数据项
     * {
     "id": 31,
     "biaoti": "标题1",
     "neirong": "内容1",
     "shipin": "",
     "fabushijian": "2024-08-05 11:59:42",
     "faburen": "发布人1",
     "fengmian": "http://localhost:8080/springboot49j18/upload/xinwen_fengmian1.jpg",
     "thumbsupnum": 1,
     "crazilynum": 1,
     "clicktime": "2024-08-05 12:00:04",
     "clicknum": 4,
     "addtime": "2024-08-05 11:59:29"
     }
     */
    
    export default class NewsDataItem {
      public id: number
      public biaoti: string
      public neirong: string
      public shipin: string
      public fabushijian: string
      public faburen: string
      public fengmian: string
      // API12的语法,如果构造函数中该属性作为形式参数且是可选参数时,要保持类型一致
      public thumbsupnum: number
      public crazilynum: number
      public clicktime: string
      public clicknum: number
      public addtime: string
    
      /**
       * 构造函数
       * @param id
       * @param biaoti
       * @param neirong
       * @param shipin
       * @param fabushijian
       * @param faburen
       * @param fengmian
       * @param thumbsupnum
       * @param crazilynum
       * @param clicktime
       * @param clicknum
       * @param addtime
       */
      constructor(id: number, biaoti: string, neirong: string, shipin: string, fabushijian: string,
        faburen: string, fengmian: string, thumbsupnum: number, crazilynum: number, clicktime: string,
        clicknum: number, addtime: string) {
        this.id = id
        this.biaoti = biaoti
        this.neirong = neirong
        this.shipin = shipin
        this.fabushijian = fabushijian
        this.faburen = faburen
        this.fengmian = fengmian
        this.thumbsupnum = thumbsupnum
        this.crazilynum = crazilynum
        this.clicktime = clicktime
        this.clicknum = clicknum
        this.addtime = addtime
      }
    }
    

    然后在bean目录下新建NewsData.ets类,用于封装整个后台JSON数据的中间层数据

    /**
     * 定义用于接收后台返回的json中间层数据
     * "data": {
         "total": 6,
         "pageSize": 10,
         "totalPage": 1,
         "currPage": 1,
         "list": []
     */
    import NewsDataItem from './NewsDataItem'
    
    export default class NewsData{
      public  total: number
      public  pageSize: number
      public  totalPage: number
      public  currPage: number
      public  list: Array<NewsDataItem>
    
      constructor(total: number, pageSize: number, totalPage: number, currPage: number, list: Array<NewsDataItem>) {
        this.total = total
        this.pageSize = pageSize
        this.totalPage = totalPage
        this.currPage = currPage
        this.list = list
      }
    }
    

    然后在bean目录下新建NewsResultData.ets类,用于封装整个后台JSON数据的最外层数据

    /**
     * 定义用于接收后台返回的json最外层数据
     * {
     *    code: 0,
     *    data: {}
     * }
     */
    import NewsData from './NewsData';
    
    export default class NewsResultData extends Object{
      public code: number;
      public data: NewsData;
    
      constructor(code: number,data: NewsData) {
        super();
        this.code = code;
        this.data = data;
      }
    }
    
  3. 新建ListComponentPage.ets页面,实现aboutToAppear()函数,然后在该函数中调用后台接口,最后用List组件渲染后台数据,具体代码如下:

    import NewsDataItem from '../common/bean/NewsDataItem'
    import { http } from '@kit.NetworkKit';
    import NewsResultData from '../common/bean/NewsResultData';
    import NewsData from '../common/bean/NewsData';
    
    @Preview
    @Entry
    @Component
    struct ListComponentPage {
      private httpReq = http.createHttp()
      @State listData: Array<NewsDataItem> = []
    
      aboutToAppear(): void {
        // 调用接口
        this.httpReq.request('http://localhost:8080/springboot/xinwen/list').then((resp) => {
          //console.info("---调用后台接口返回---", JSON.stringify(resp))
          if (resp !== undefined && resp !== null) {
            if (resp.responseCode == 200) {
              //console.info("---resp.result---", resp.result)
              let newsResult: NewsResultData = JSON.parse(resp.result.toString())
              //console.info("---newsData---", newsResult.code)
              if (newsResult !== undefined && resp !== null) {
                let newsData: NewsData = newsResult.data
                this.listData = newsData.list
              }
            }
          }
        }).catch((reason: object) => {
          console.info("---接口错误信息---", JSON.stringify(reason))
        })
      }
    
      build() {
        Column() {
          List({ space: 10 }) {
            ForEach(this.listData, (item: NewsDataItem) => {
              ListItem() {
                Text(`${item.biaoti}`)
                  .width('100%')
                  .height(100)
                  .fontSize(20)
                  .fontColor(Color.White)
                  .textAlign(TextAlign.Center)
                  .borderRadius(10)
                  .backgroundColor(0x007DFF)
              }
            })
          }
          // 分割线
          .divider({
            strokeWidth: 5,
            color: Color.Red,
            startMargin: 10,
            endMargin: 10
          })
          // 设置成水平方向
          // .listDirection(Axis.Horizontal)
          // 滑动事件
          .onScrollIndex((firstIndex: number, lastIndex: number) => {
            console.info('滑动起始位置索引值' + firstIndex)
            console.info('滑动结束位置索引值' + lastIndex)
          })
          .onDidScroll((scrollOffset: number, scrollState: ScrollState) => {
            console.info('滑动偏移量' + scrollOffset)
            console.info('当前滑动状态' + scrollState)
          })
          .onReachStart(() => {
            console.info('列表起始位置到达')
          })
          .onReachEnd(() => {
            console.info('列表末尾位置到达')
          })
          .onScrollStop(() => {
            console.info('列表滑动停止')
          })
        }
        .padding(12)
        .height('100%')
        .backgroundColor(0xF1F3F5)
    
      }
    }
    
  4. 重新编译,运行效果如下:
    在这里插入图片描述

三、总结

有如下关键几点:

  1. 调用后台接口,需要引入http模块或者其他诸如Ajax、axios等网络请求模块;
  2. 如果是需要在页面被创建的时候调用后台接口,则需要在aboutToAppear()中进行调用,如需要在页面显示时需要调用后台接口加载数据,则可以在onPageShow()函数中进行调用。根据实际业务结合组件的生命周期进行合适的调用;
  3. 如使用JSON.parse报错Structural typing is not supported (arkts-no-structural-typing),其原因是引入import { JSON } from '@kit.ArkTS';模块中的JSON,需要将其删除掉,使用内置的JSON对象(不需要显示引用);
调用React的生命周期方法是由React框架自动管理的,不需要手动调用。当组件被创建、更新或卸载时,React会自动调用相应的生命周期方法。以下是React常用的生命周期方法调用顺序: 1. 创建阶段: - constructor(props):组件的构造函数,在组件被创建时调用,用于初始化组件的状态和绑定事件等操作。 - static getDerivedStateFromProps(props, state):在组件被创建或接收到新的props时调用,用于根据props更新组件的状态。 - render():渲染组件的内容。 - componentDidMount():在组件被挂载到DOM后调用,用于执行一些需要DOM的操作,如数据获取、订阅事件等。 2. 更新阶段: - static getDerivedStateFromProps(props, state):在组件接收到新的props时调用,用于根据props更新组件的状态。 - shouldComponentUpdate(nextProps, nextState):在组件更新前调用,用于判断是否需要重新渲染组件,默认返回true。 - render():渲染组件的内容。 - getSnapshotBeforeUpdate(prevProps, prevState):在组件更新前调用,用于获取更新前的DOM状态,返回值将作为componentDidUpdate()的第三个参数传递。 - componentDidUpdate(prevProps, prevState, snapshot):在组件更新后调用,用于执行一些更新后的操作,如更新DOM、发送网络请求等。 3. 卸载阶段: - componentWillUnmount():在组件从DOM中移除前调用,用于清理组件的副作用,如取消订阅、清除定时器等。 需要注意的是,React 16.3版本之后,一些生命周期方法已经被废弃或替代,具体使用哪些生命周期方法取决于React版本和组件的需求。以上是常用的生命周期方法调用顺序,具体使用时请参考React官方文档或相关教程。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [react生命周期详细介绍](https://blog.csdn.net/luobo2345/article/details/122818947)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若兰幽竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值