鸿蒙项目中遇到的知识点(商城类)

1、一多开发模式简介

①什么是“一多开发模式”

答案

一多开发模式指的是:一套工程代码,一次开发上架,多段按需部署,本质上是为了让开发者快速高效的开发支持多端设备形态的应用。

两个明显要解决的问题:1、不同设备之间的UI如何适配;2、不同设备之间的系统能力如何适配。

②一多下的页面开发适配

        1. 自适应布局

                答案:针对常见的开发场景,方舟开发框架提炼了七种自适应布局能力,这些布局可以独立使用,也可多种布局叠加使用

能力类别

使用场景

实现方式

拉伸能力

容器组件尺寸发生变化时,增加或减小的空间全部分配给容器组件内指定区域

Flex布局的flexGrow和flexShrink属性

均分能力

容器组件尺寸发生变化时,增加或减小的空间均匀分配给容器组件内所有空白区域

Row组件Column组件Flex组件的justifyContent属性设置为FlexAlign.SpaceEvenly

占比能力

子组件的宽或高按照预设的比例,随容器组件发生变化

基于通用属性的两种实现方式:

  • 将子组件的宽高设置为父组件宽高的百分比
  • layoutWeight属性

缩放能力

子组件的宽高按照预设的比例,随容器组件发生变化,且变化过程中子组件的宽高比不变

布局约束的aspectRatio属性

延伸能力

容器组件内的子组件,按照其在列表中的先后顺序,随容器组件尺寸变化显示或隐藏

基于容器组件的两种实现方式:

隐藏能力

容器组件内的子组件,按照其预设的显示优先级,随容器组件尺寸变化显示或隐藏。相同显示优先级的子组件同时显示或隐藏

布局约束的displayPriority属性

折行能力

容器组件尺寸发生变化时,如果布局方向尺寸不足以显示完整内容,自动换行

Flex组件的wrap属性设置为FlexWrap.Wrap

        2. 响应式布局

                答案:自适应布局可以保证窗口在一定范围内变化时,页面显示是正常的,但是如果窗口尺寸变化比较大的时候,仅依赖自适应布局有可能出现图片异常放大或者页面内容稀疏、留白过多等问题,此时就需要结合响应式布局调整页面结构

响应式布局能力

简介

断点

将窗口宽度划分为不同的范围(即断点),监听窗口尺寸变化,当断点改变时同步调整页面布局。

媒体查询

媒体查询支持监听窗口宽度、横竖屏、深浅色、设备类型等多种媒体特征,当媒体特征发生改变时同步调整页面布局。

栅格布局

栅格组件将其所在的区域划分为有规律的多列,通过调整不同断点下的栅格组件的参数以及其子组件占据的列数等,实现不同的布局效果。

2、一多下的系统能力适配(了解)

①一个前提

功能开发的适配主要体现在需要适配不同范类的应用,比如既要适配手机和平板,也需要适配智能穿戴设备,如果是同泛类产品,系统能力一致,无需考虑多设备上应用功能开发的差异,我们的美寇商城需要适配的是手机和Pad,属于同泛类产品,无需考虑功能开发的差异。以下是常见类型分类:

  • 默认设备(一般为手机)、平板
  • 车机、智慧屏
  • 智能穿戴

②什么是系统能力

系统能力(即SystemCapability,缩写为SysCap)指操作系统中每一个相对独立的特性,如蓝牙,WIFI,NFC,摄像头等,都是系统能力之一。每个系统能力对应多个API,随着目标设备是否支持该系统能力共同存在或消失。

如何适配系统能力

方法1: 使用canUse接口判断设备是否支持某系统能力                               

if (canIUse("SystemCapability.Communication.NFC.Core")) {
   console.log("该设备支持SystemCapability.Communication.NFC.Core")
} else {
   console.log("该设备不支持SystemCapability.Communication.NFC.Core")
}

方法2:通过import动态导入,配合try/catch

import controller from '@ohos.nfc.controller'
try {
    controller.enableNfc()
    console.log("controller enableNfc success")
} catch (busiError) {
    console.log("controller enableNfc busiError: " + busiError)
}

注意:如果某系统能力是应用运行必须的,则要将其写入到应用的要求能力集中,以确保应用不会分发和安装到不符合要求的设备上。如果某系统能力不是应用运行必须的,则可以在运行时做动态判断,这样可以最大程度扩大应用的适用范围。

3、一多下的工程代码结构

一多模式下,官方推荐在开发过程中采用"三层工程架构",其实就是把项目拆分成不同类型的模块,再通过模块之间的引用组合,最终实现应用功能,拆分规范如下:

  • common(公共能力层):用于存放公共基础能力合集,比如工具库,公共配置等
  • features(基础特性层):用于存放应用中相对独立的各个功能的UI以及业务逻辑实现
  • product(产品定制层):用于针对不同设备形态进行功能和特性集成,作为应用入口
  1. common设计为har包,新建module时选择Static Library, 内部存放全局通用的工具函数,公共配置等
  2. feature设计为har包,新建module时选择 Static Library, 内部存放相对独立的业务单元,比如购物车我的分类Home ,也就是首页底部Tab切换时的四个核心业务模块
  3. product为产品层,里面放置phone模块,也就是入口模块,在phone中我们放置入口ability和所有页面级别的组件

以上就是我们本次项目的"三层工程架构" 的基础约定,他们之间存在一定的依赖关系,核心依赖关系如下图所示:

4、环境和通用工具配置

①模块依赖安装使用

模块之间不是孤立的,是可以互相依赖的,如果互相依赖,需要在模块下的oh-package.json5 文件中添加依赖并安装,安装之后才能使用对应模块, 比如phone依赖了features中的所有模块和common模块,可以进行如下配置:

{
  "license": "",
  "devDependencies": {},
  "author": "",
  "name": "phone",
  "description": "Please describe the basic information.",
  "main": "",
  "version": "1.0.0",
  "dependencies": {
    "@meikou/My": "file:../../features/My",
    "@meikou/ShopCart": "file:../../features/ShopCart",
    "@meikou/common": "file:../../common",
    "@meikou/home": "file:../../features/Home",
    "@meikou/category":"file:../../features/Category"
  }
}

:key为使用模块时的名字,它只是一个标识,保持规范即可,value为模块的实际地址,不能写错,当我们在dependencies选项中进行模块配置之后,注意IDE顶部会提示安装模块,点击Sync Now即可完成安装,安装之后在phone模块中就可以使用 features和common了

②axios工具安装和基础配置

OpenHarmony三方库中心仓

简介:Axios ,是一个基于 promise 的网络请求库,可以运行 node.js 和浏览器中。本库基于Axios 原库v1.3.4版本进行适配,使其可以运行在 OpenHarmony,并沿用其现有用法和特性。

        1、安装axios:ohpm install @ohos/axios

        2、实例化axios:

import axios, { InternalAxiosRequestConfig, AxiosError, AxiosResponse } from '@ohos/axios'

// 实例化 通用配置
const httpInstance = axios.create({
  baseURL: 'https://meikou-api.itheima.net/',
  timeout: 5000
})

// 拦截器配置
// 请求拦截器
// token配置等
httpInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  return config
}, (error: AxiosError) => {
  return Promise.reject(error)
})


// 添加响应拦截器
// 错误统一处理等
httpInstance.interceptors.response.use((response: AxiosResponse) => {
  return response
}, (error: AxiosError) => {
  return Promise.reject(error)
})

export { httpInstance }

        3、导出axios实例:export { httpInstance } from './src/main/ets/utils/Http'

        4、开通网络权限:应用在发送网络请求之前,需要先在module.json5配置文件中声明网络权限,否则无法发起请求

"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]

        5、示例

 // 基于类型的请求使用方式
      const res = await httpInstance.request<null,AxiosResponse<HttpResType<Result[]>,null>,null>({
        url:'/home/banner',
        method:'GET'
      })

5、规范化请求

上面我们简单对axios做了简单测试,存在一些问题,需要我们解决

  1. 请求直接放到了组件中进行,和组件耦合在一起,没有做统一管理
  2. 类型写法太过繁琐,使用不方便

①在apis中统一封装业务请求函数 

新增apis文件夹,新建一个banner.ets业务接口文件,我们以获取Banner接口为例,进行业务接口函数封装:

import { httpInstance } from '@meikou/common'
import { AxiosResponse } from '@ohos/axios'

// 业务接口通用返回类型
interface HttpResType<T> {
  code: string
  msg: string
  result: T
}

// 业务接口特有返回类型
interface Result {
  hrefUrl: string;
  id: string;
  imgUrl: string;
  type: string;
}

export function getBannerAPI(){
  return  httpInstance.request<null,AxiosResponse<HttpResType<Result>,null>,null>({
    url:'/home/banner',
    method:'GET'
  })
}

业务组件中使用:

import { getBannerAPI } from '../apis/banner'

@Entry
@Component
struct Index {
  build() {
    Button('click').onClick(async ()=>{
      // 基于类型的请求使用方式
      const res = await getBannerAPI()
      console.log('banner:',JSON.stringify(res.data))
    })
  }
}

②优化类型使用

当前问题:在业务接口函数封装的过程中,request方法传递的类型参数过于复杂,不够直观

解决办法:抽象一个单独的泛型函数,把复杂写法封装到内部,对外保留简单的API,使用样例如下所示:

fetchData<Result>({
  url:'/home/banner',
  method:'GET'
})
  1. 新增一个泛型函数fetchData,接收业务接口返回的具体类型传入
  2. fetchData函数接受一个和axios请求对象一样的参数
  3. fetchData函数返回值依旧是一个promise对象

封装如下:

import { httpInstance } from '@meikou/common'
import { AxiosRequestConfig, AxiosResponse } from '@ohos/axios'

// 业务接口通用返回类型
interface HttpResType<T> {
  code: string
  msg: string
  result: T
}

// 业务接口特有返回类型
interface Result {
  hrefUrl: string;
  id: string;
  imgUrl: string;
  type: string;
}

// 抽象通用泛型
function fetchData<T>(reqData: AxiosRequestConfig):Promise<AxiosResponse<HttpResType<T>,null>>{
  return httpInstance.request<null,AxiosResponse<HttpResType<T>,null>,null>(reqData)
}

export function getBannerAPI(){
  return fetchData<Result>({
    url:'/home/banner',
    method:'GET'
  })
}

③把fetchData放入common模块 

通用类型HttpResTypefetchData函数在很多个业务模块中都需要使用,所以我们把它俩也放置common中,统一导出fetchData函数即可,业务API中只需要引入fetchData使用

// 业务接口通用返回类型
interface HttpResType<T> {
  code: string
  msg: string
  result: T
}

// 抽象通用泛型
function fetchData<T>(reqData: AxiosRequestConfig):Promise<AxiosResponse<HttpResType<T>,null>>{
  return httpInstance.request<null,AxiosResponse<HttpResType<T>,null>,null>(reqData)
}


export { httpInstance,HttpResType,fetchData }

6、Logger工具配置

OpenHarmony三方库中心仓

①安装到项目

ohpm install @abner/log

②全局初始化:

为了让全局生效,可以在EntryAblility中进行统一配置,这样所有的page都将可用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值