【入门到精通】鸿蒙next开发:基于H5框架的多设备开发指南

往期鸿蒙5.0全套实战文章必看:(文中附带全栈鸿蒙5.0学习资料)


基于H5框架的多设备开发指南

1. 概述

应用使用H5开发的历史页面多且冗杂,同时H5相较于ArkUI一多缺乏拿来即用的适配方案。为达到OpenHarmony一多体验,所有页面进行一多适配复杂且工作量大。针对此问题,本文将主要提供一套H5多设备断点和响应式组件方案,实现页签栏响应式、网格响应式、类挪移布局等效果,提升H5一多适配的开发效率。首先介绍多设备断点能力,然后分别介绍组件的使用说明,结合组件效果提供对应场景的开发案例,最终提供示例代码指导实际开发。

以下是使用组件库的一些前置要求:

组件库安装

根据您使用的包管理器和web框架,请选择对应的安装命令。

Npm

​// Vue2 
npm install @hadss/web_adaptive_layout_vue2 
// Vue3 
npm install @hadss/web_adaptive_layout_vue3 
// React 
npm install @hadss/web_adaptive_layout_react

Yarn

​// Vue2 
yarn add @hadss/web_adaptive_layout_vue2 
// Vue3 
yarn add @hadss/web_adaptive_layout_vue3 
// React 
yarn add @hadss/web_adaptive_layout_react

2. 多设备断点

2.1 断点设计原理

H5断点是基于鸿蒙多设备封装的一套断点机制,通过设置断点,让开发者可以结合窗口宽度去实现不同的页面布局效果。

断点以应用窗口宽度为基准,将应用窗口在宽度维度上分成了几个不同的区间即不同的断点,默认提供的断点区间如下所示。

横向断点名称

取值范围(px

xs

[0, 320)

sm

[320, 600)

md

[600, 840)

lg

[840, 1440)

xl

[1440, +∞)

纵向断点名称

取值范围(高宽比)

sm

(0,0.8)

md

[0.8 , 1.2)

lg

[1.2,+∞)

开发者可以根据实际需要调整默认的断点区间,也可以在xl后面新增xxl断点以适配更复杂的布局场景。

2.2 多设备适配指导

在具体开发过程中,使用breakpointManager需先从@hadss/web_adaptive_layout_ui引用BreakpointManager这个类,然后创建BreakpointManager实例。建议创建BreakpointManager实例放在公共文件里,然后导出。这样的话,设备断点值变更时就只需要调整一个地方。使用breakpointManager时,需调用subscribeToBreakpoint方法订阅断点变化,然后在回调函数里使用useBreakpointValue方法来获取不同断点下属性的不同值。最后在页面销毁前需要取消断点订阅并销毁实例。

具体示例如下所示:

创建断点管理公共实例并导出

​// utils/breakpointInit.ts 
import { BreakpointManager } from "@hadss/web_adaptive_layout_ui"; 
 
// 实例化断点管理类,断点区间支持自定义 
export const breakpointManager = new BreakpointManager({ 
  xs: 0, 
  sm: 320, 
  md: 600, 
  lg: 840, 
  xl: 1440, 
});

订阅断点变化并获取不同断点下的属性值

// xxx.vue 
import { breakpointManager } from "./utils/breakpointInit"; 
 
const contentCols = ref("12"); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint((bp,vbp) => { 
  // bp:实时的横向断点回调,为null时不使用横向断点
  // vbp:实时纵向断点回调,为null时不使用纵向断点
  // 根据当前断点区间,返回对应的属性值 
  contentCols.value = breakpointManager.useBreakpointValue({ 
    xs: "12", 
    sm: "12", 
    md: "6", 
    lg: "6", 
    xl: "6", 
  }); 
  // 获取当前的横向断点值 
  breakpointManager.getCurrentBreakpoint(); 
  // 获取当前的纵向断点值
  breakpointManager.getCurrentVerticalBreakpoint();
  // 获取当前的内置断点类型和区间 
  breakpointManager.getBreakpoints(); 
});

页面销毁前取消断点订阅并销毁实例

// xxx.vue 
onUnmounted(() => { 
  // 取消订阅 
  unsubscribe(); 
  // 销毁实例,移除监听器,清空回调函数集合 
  breakpointManager.destroy(); 
});

如果当前应用使用的API≥13,可以使用OpenHarmony提供的断点接口:getWindowWidthBreakpointgetWindowHeightBreakpoint,获取横向和纵向断点。通过前端页面调用应用侧函数的方法,将断点值传到H5页面,通信接口使用方式可参考官网指南前端页面调用应用侧函数

3. 页签栏响应式组件实现多设备适配

3.1 组件使用说明

H5页签栏响应式组件MultiTabBar,包含父组件TabBar和子组件TabBarItem两部分,主要用于实现内容视图切换的布局效果。组件结合多设备断点能力,能够适配不同类型的布局场景。

组件导入方式

1、Vue2

// xxx.vue 
import { TabBarVue, TabBarItemVue } from "@hadss/web_adaptive_layout_vue2";

2、Vue3

// xxx.vue 
import { TabBarVue, TabBarItemVue } from "@hadss/web_adaptive_layout_vue3";

3、React

// xxx.tsx 
import { TabBarReact, TabBarItemReact } from "@hadss/web_adaptive_layout_react";

默认布局效果

MultiTabBar组件基于默认断点区间,内置了一套多设备布局效果,如下图所示

sm

md

lg

15.png

16.png

17.png

TabBar父组件 API

1、Attribute

属性

说明

类型

可选值

默认值

vertical

设置组件是否为纵向Tab

Boolean

true:纵向Tab

false:横向Tab

xs:false

sm:false

md:false

lg:true

xl:true

barPosition

设置组件的位置

String

start

vertical属性设置为true时,Tab位于容器左侧;

vertical属性设置为false时,Tab位于容器顶部。

end

vertical属性设置为true时,Tab位于容器右侧;

vertical属性设置为false时,Tab位于容器底部。

xs:bottom

sm:bottom

md:bottom

lg:left

xl:left

width

设置组件的宽度

String / Number

xs:100%

sm:100%

md:100%

lg:58px

xl:58px

height

设置组件的高度

String / Number

xs:78px

sm:78px

md:78px

lg:100%

xl:100%

unselectedColor

设置子组件文本未选中时的颜色

String

#aaacab

selectedColor

设置子组件文本选中时的颜色

String

#0b59f7

layoutMode

设置子组件内部元素的排布方式

String

vertical:元素垂直排布

horizontal:元素水平排布

xs:vertical

sm:vertical

md:horizontal

lg:vertical

xl:vertical

verticalAlign

设置子组件内部元素在垂直方向上的对齐方式

String

top:顶部对齐

center:居中对齐

bottom:底部对齐

center

horizontalAlign

设置子组件内部元素在水平方向上的对齐方式

String

start:起始端对齐

center:居中对齐

end:末端对齐

center

bgColor

设置子组件容器未选中时的背景颜色

String

#ffffff

selectedBgColor

设置子组件容器选中时的背景颜色

String

#f1f5ff

2、Event

事件名

说明

参数

onTabItemClick

点击页签栏子组件容器时触发的自定义事件

Function({indexname})

index:选中子组件的索引值

name:选中子组件的name标识名称

TabBarItem子组件 API

属性

说明

类型

可选值

默认值

name

子组件的唯一标识名称(必填)

String

推荐使用方式(以Vue3为例)

MultiTabBar组件在使用时建议封装为一个独立的组件,置于嵌套路由RouterView外层,以确保页面切换时组件不会刷新。同时,需要借助断点能力实现路由视图的页签栏避让。

// APP.vue 
<template> 
  <div> 
    <TabBar /> 
    <div class="template-main"> 
      <router-view /> 
    </div> 
  </div> 
</template> 
 
<script setup> 
import { ref, onUnmounted } from "vue"; 
// 导入封装后的MultiTabBar组件 
import TabBar from "./components/TabBar/index.vue"; 
// 导入断点公共实例 
import { breakpointManager } from "./utils/breakpointInit"; 
 
const marginLeft = ref("0"); 
const marginBottom = ref("0"); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  // 传入不同断点下的属性值,根据当前断点返回对应的值 
  marginLeft.value = breakpointManager.useBreakpointValue({ 
    xs: 0, 
    sm: 0, 
    md: 0, 
    lg: "96px", 
    xl: "96px", 
  }); 
  marginBottom.value = breakpointManager.useBreakpointValue({ 
    xs: "78px", 
    sm: "78px", 
    md: "78px", 
    lg: 0, 
    xl: 0, 
  }); 
  // 设置CSS变量 
  document.documentElement.style.setProperty("--marginLeft", marginLeft.value); 
  document.documentElement.style.setProperty("--marginBottom", marginBottom.value); 
}); 
onUnmounted(() => { 
  // 取消订阅断点变化 
  unsubscribe(); 
  // 销毁实例,移除监听器,清空回调函数集合 
  breakpointManager.destroy(); 
}); 
</script> 
 
<style lang="less" scoped> 
.template-main { 
  // 设置margin样式,实现页签栏避让 
  margin-left: var(--marginLeft); 
  margin-bottom: var(--marginBottom); 
  overflow: scroll; 
} 
</style>

MultiTabBar组件封装示例代码如下所示:

// TabBar/index.vue 
<template> 
  <TabBarVue :onTabItemClick="tabItemClick" 
             :vertical="vertical"> 
    <TabBarItemVue v-for="item in tabItems"  
                   :name="item.name"  
                   :key="item.key"> 
      <img :src="item.imgSrc" /> 
      <span>{{ item.name }}</span> 
    </TabBarItemVue> 
  </TabBarVue> 
</template> 
 
<script setup> 
import { ref, onUnmounted } from "vue"; 
import { TabBarVue, TabBarItemVue } from "@hadss/web_adaptive_layout_vue3"; 
import { breakpointManager } from "../../utils/breakpointInit"; 
 
const vertical = ref(false); 
const tabItems = ref([ 
  { key: "first", name: "首页", imgSrc: "../assets/tab_home_selected.svg", urlName: "/" }, 
  { key: "second", name: "分类", imgSrc: "../assets/tab_classification.svg", urlName: "/classify" }, 
  { key: "third", name: "发现", imgSrc: "../assets/tab_discovery.svg", urlName: "/discovery" }, 
]); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  // 传入不同断点下的vertical属性值,根据当前断点返回对应的值 
  vertical.value = breakpointManager.useBreakpointValue({ 
    xs: false, 
    sm: false, 
    md: false, 
    lg: true,  
    xl: true, 
  }); 
}); 
// 定义自定义事件 
const tabItemClick = ({ index, name }) => { 
  // 添加点击事件逻辑 
}; 
onUnmounted(() => { 
  // 取消订阅断点变化 
  unsubscribe(); 
}); 
</script>

3.2 场景案例

实现效果

注意:实现效果中的红色框仅表示组件位置,不代表对应组件的边框。

sm

md

lg

18.png

19.png

20.png

关键代码(以vue3为例)

  • onTabItemClick为组件绑定的点击事件,可以在这里实现点击切换图片的效果已及点击进行路由跳转的功能。
  • vertical属性可以设置页签栏是否为纵向,true表示纵向左边tab,false为横向底部tab。(暂不支持其他位置的tab)。​​​

更多属性及参数参考 页签栏组件MultiTabBar

代码示例如下:

// web_advanced_ui_sample\vue3_sample\src\App.vue 
<template> 
  <div> 
    <TabBar /> 
    <div class="template-main"> 
      <router-view /> 
    </div>  
  </div> 
</template>
// web_advanced_ui_sample\vue3_sample\src\components\TabBar\index.vue 
<template> 
  <TabBarVue :onTabItemClick="tabItemClick"  
             :vertical="vertical"  
             :selectedBgColor="selectedBgColor"  
             :bgColor="defaultBgColor" 
             :selectedColor="selectedColor"  
             :width="barWidth" 
             :layoutMode="layoutMode" > 
    <TabBarItemVue v-for="item in tabItems"  
                   :name="item.key"  
                   :key="item.key"> 
      <img :src="item.imgSrc" /> 
      <span>{{ item.name }}</span> 
    </TabBarItemVue> 
  </TabBarVue> 
</template> 
 
<script setup> 
import { ref, onUnmounted } from "vue"; 
import { TabBarVue, TabBarItemVue } from "@hadss/web_adaptive_layout_vue3"; 
import { breakpointManager } from "../../utils/breakpointInit"; 
import { useRouter } from "vue-router"; 
 
const router = useRouter(); 
// 导航栏文本图片信息 
const tabItems = ref([ 
  { key: "first", name: "首页", imgSrc: "../assets/tab_home_selected.svg", urlName: "/" }, 
  { key: "second", name: "分类", imgSrc: "../assets/tab_classification.svg", urlName: "/classify" }, 
  { key: "third", name: "发现", imgSrc: "../assets/tab_discovery.svg", urlName: "/discovery" }, 
  { key: "forth", name: "购物袋", imgSrc: "../assets/tab_shopping_bag.svg", urlName: "/shoppingBag" }, 
  { key: "fivth", name: "我的", imgSrc: "../assets/tab_mine.svg", urlName: "/mine" }, 
]); 
const vertical = ref(false); 
const selectedBgColor = ref("#f1f3f5"); 
const defaultBgColor = ref("#f1f3f5"); 
const barWidth = ref("100%"); 
const selectedColor = ref("#d20a2c"); 
const layoutMode = ref("vertical"); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  vertical.value = breakpointManager.useBreakpointValue({ 
    xs: false, 
    sm: false, 
    md: false, 
    lg: true,  
    xl: true, 
  }); 
  barWidth.value = breakpointManager.useBreakpointValue({ 
    xs: "100%", 
    sm: "100%", 
    md: "100%", 
    lg: "98px", 
    xl: "98px", 
  }); 
}); 
// 页签栏点击事件:切换路由,更换icon图标 
const tabItemClick = ({ index }) => { 
  let item = tabItems.value[index]; 
  router.push(item.urlName); 
  for (let i = 0; i < tabItems.value.length; i++) { 
    let curItem = tabItems.value[i]; 
    if (curItem.imgSrc.endsWith("_selected.svg")) { 
      curItem.imgSrc = curItem.imgSrc.replace("_selected.svg", ".svg"); 
    } 
    if (index === i && !curItem.imgSrc.endsWith("_selected.svg")) { 
      curItem.imgSrc = curItem.imgSrc.replace(".svg", "_selected.svg"); 
    } 
  } 
}; 
// 取消订阅,销毁断点实例 
onUnmounted(() => { 
  unsubscribe(); 
  breakpointManager.destroy(); 
}); 
</script> 
 
<style lang="less" scoped> 
@import './index.less'; 
</style>

4. 网格布局响应式组件实现多设备适配

4.1 组件使用说明

H5网格布局响应式组件MultiGrid,包含父组件MultiGrid和子组件MultiGridItem两部分,主要用于提供精确的行和列控制,实现复杂的二维布局效果。组件结合多设备断点能力,能够适配不同类型的布局场景。

组件导入方式

1、Vue2

// xxx.vue 
import { MultiGridVue, GridItemVue } from "@hadss/web_adaptive_layout_vue2";

2、Vue3

// xxx.vue 
import { MultiGridVue, GridItemVue } from "@hadss/web_adaptive_layout_vue3";

3、React

// xxx.tsx 
import { MultiGridReact, GridItemReact } from "@hadss/web_adaptive_layout_react";

默认布局效果

MultiGrid组件基于默认断点区间,内置了一套多设备布局效果,如下图所示

sm

md

lg

21.png

22.png

23.png

MultiGrid父组件 API

1. Attribute

属性

说明

类型

可选值

默认值

columnsTemplate

设置组件每一列的列宽

String / Number

1. 绝对单位

2. 百分比

3. repeat(),接受两个参数:

(1) 参数1:重复的次数,参数2:需要重复的值

(2) 参数1:auto-fill关键字表示自动填充,参数2:每列宽度

(3) 参数1:auto-fit关键字表示自动填充,宽度不够时会缩小

3. fr关键字:表示比例关系

4. minmax():接受最小值和最大值两个参数

5. auto关键字:浏览器自己决定长度

xs:1fr 1fr 1fr 1fr

sm:1fr 1fr 1fr 1fr

md:1fr 1fr 1fr 1fr 1fr 1fr

lg:1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr

xl:1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr

rowsTemplate

设置组件每一行的行高

String / Number

同columnsTemplate

auto

gridRowGap

设置网格行与行的间隔

String / Number

0

gridColumnGap

设置网格列与列的间隔

String / Number

0

justifyItems

设置网格项内容的水平位置

String

stretch:拉伸以填充网格项

start:网格项起点位置对齐

end:网格项终点位置对齐

center:网格项中间位置对齐

stretch

alignItems

设置网格项内容的垂直位置

String

stretch:拉伸以填充网格项

start:网格项起点位置对齐

end:网格项终点位置对齐

center:网格项中间位置对齐

stretch

justifyContent

设置整个内容区域在容器里的水平位置

String

stretch:未指定大小时拉伸填充容器

start:对齐容器的起始边框

end:对齐容器的结束边框

center:容器内容居中

space-around:子项两侧间隔相等

space-between:子项间间隔相等,与容器边框无间隔

space-evenly:子项间间隔相等

stretch

alignContent

设置整个内容区域在容器里的垂直位置

String

同justifyContent,方向为垂直方向

stretch

2. Event

事件名

说明

参数

onGridItemClick

点击网格子组件容器时触发的自定义事件

Function({indexname})

index:选中子组件的索引值

name:选中子组件的name标识名称

MultiGridItem子组件 API

属性

说明

类型

可选值

默认值

name

子组件的唯一标识名称(必填)

String

gridColumnStart

设置子组件左边框所在的起始列号

String / Number

auto

gridColumnEnd

设置子组件右边框所在的终点列号

String / Number

auto

gridRowStart

设置子组件上边框所在的起始行号

String / Number

auto

gridRowEnd

设置子组件下边框所在的终点行号

String / Number

auto

label

设置网格项的文本内容(不支持断点)

String

icon

设置网格项的图标链接(不支持断点,只支持网络链接)

String

推荐使用方式(以Vue3为例)

// MultiGrid/index.vue 
<template> 
  <MultiGridVue :onGridItemClick="gridItemClick" 
                :columnsTemplate="columnsTemplate"> 
    <GridItemVue v-for="item in gridItems"  
                 :name="item.name"  
                 :key="item.id"> 
      <img :src="item.imgSrc" /> 
      <span>{{ item.name }}</span> 
    </GridItemVue> 
  </MultiGridVue> 
</template> 
 
<script setup> 
import { ref, onUnmounted } from "vue"; 
import { MultiGridVue, GridItemVue } from "@hadss/web_adaptive_layout_vue3"; 
import { breakpointManager } from "../../utils/breakpointInit"; 
 
const columnsTemplate = ref("1fr 1fr 1fr 1fr 1fr"); 
const gridItems = ref([ 
  { id: 1, name: "智慧办公", imgSrc: require("../../assets/categories_1.png") }, 
  { id: 2, name: "智慧家居", imgSrc: require("../../assets/categories_2.png") }, 
  { id: 3, name: "智能手机", imgSrc: require("../../assets/categories_3.png") }, 
]); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  // 传入不同断点下的columnsTemplate属性值,根据当前断点返回对应的值 
  columnsTemplate.value = breakpointManager.useBreakpointValue({ 
    xs: "1fr 1fr 1fr 1fr 1fr", 
    sm: "1fr 1fr 1fr 1fr 1fr", 
    md: "1fr 1fr 1fr 1fr 1fr 1fr 1fr", 
    lg: "1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr",  
    xl: "1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr", 
  }); 
}); 
// 定义自定义事件 
const gridItemClick = ({ index, name }) => { 
  // 添加点击事件逻辑 
}; 
onUnmounted(() => { 
  // 取消订阅断点变化 
  unsubscribe(); 
  // 销毁实例,移除监听器,清空回调函数集合 
  breakpointManager.destroy(); 
}); 
</script>

4.2 场景案例

实现效果

注意:实现效果中的红色框仅表示组件位置,不代表对应组件的边框。

sm

md

lg

24.png

25.png

26.png

关键代码(以vue3为例)

  • 网格列数通过columnsTemplate设置,结合breakpointManager断点管理即可实现在不同设备上展示不同的列数。本示例中以fr关键字设置列数。
  • onGridItemClick为组件MultiGridVue自带的点击事件,在vue3中也可以在GridItemVue里添加@click点击事件,但是在vue2中建议使用onGridItemClick实现子组件的点击事件。

其他设置方式及其他属性参考 网格组件multigrid

具体示例如下:

// web_advanced_ui_sample\vue3_sample\src\components\Categories\index.vue 
<template> 
  <div class="categories"> 
    <MultiGridVue :columnsTemplate="columnsTemplate"  
                  gridRowGap="10px"  
                  gridColumnGap="10px" 
                  onGridItemClick="pageJump"> 
      <GridItemVue class="categories-item" 
                   v-for="item in categoriesItems"  
                   :name="item.key"  
                   :key="item.key"> 
        <img :src="item.imgSrc" /> 
        <span>{{ item.name }}</span> 
      </GridItemVue> 
    </MultiGridVue> 
  </div> 
</template> 
 
<script setup> 
import { ref, onUnmounted } from "vue"; 
import { MultiGridVue, GridItemVue } from "@hadss/web_adaptive_layout_vue3"; 
import { breakpointManager } from "../../utils/breakpointInit"; 
import { useRouter } from "vue-router"; 
 
const router = useRouter(); 
// 网格项点击事件:路由跳转 
const pageJump = () => { 
  router.push("detail_pay"); 
}; 
// 网格组件元素 
const categoriesItems = [ 
  { id: 1, name: "智慧办公", imgSrc: require("../../assets/categories_1.png") }, 
  { id: 2, name: "华为手机", imgSrc: require("../../assets/categories_2.png") }, 
  { id: 3, name: "运动健康", imgSrc: require("../../assets/categories_3.png") }, 
  { id: 4, name: "华为智选", imgSrc: require("../../assets/categories_4.png") }, 
  { id: 5, name: "企业商用", imgSrc: require("../../assets/categories_5.png") }, 
  { id: 6, name: "智慧家居", imgSrc: require("../../assets/categories_6.png") }, 
  { id: 7, name: "影音娱乐", imgSrc: require("../../assets/categories_7.png") }, 
  { id: 8, name: "AITO汽车", imgSrc: require("../../assets/categories_8.png") }, 
  { id: 9, name: "鸿蒙智联", imgSrc: require("../../assets/categories_9.png") }, 
  { id: 10, name: "全屋智能", imgSrc: require("../../assets/categories_10.png") }, 
]; 
const columnsTemplate = ref("1fr 1fr 1fr 1fr 1fr"); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  columnsTemplate.value = breakpointManager.useBreakpointValue({ 
    xs: "1fr 1fr 1fr 1fr 1fr", 
    sm: "1fr 1fr 1fr 1fr 1fr", 
    md: "1fr 1fr 1fr 1fr 1fr 1fr 1fr", 
    lg: "1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr", 
    xl: "1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr", 
  }); 
}); 
// 取消订阅,销毁断点实例 
onUnmounted(() => { 
  unsubscribe(); 
  breakpointManager.destroy(); 
}); 
</script> 
 
<style lang="less" scoped> 
@import './index.less'; 
</style>

5. 类挪移布局响应式组件实现多设备适配

5.1 组件使用说明

H5类挪移布局响应式组件MultiDiversion,包含父组件MultiDiversion和子组件MultiDiversionItem两部分,主要用于根据布局的宽度选择是上下布局还是左右布局效果。组件结合多设备断点能力,能够适配不同类型的布局场景。

组件导入方式

1、Vue2

// xxx.vue 
import { MultiDiversionVue, DiversionItemVue } from "@hadss/web_adaptive_layout_vue2";

2、Vue3

// xxx.vue 
import { MultiDiversionVue, DiversionItemVue } from "@hadss/web_adaptive_layout_vue3";

3、React

// xxx.tsx 
import { MultiDiversionReact, DiversionItemReact } from "@hadss/web_adaptive_layout_react";

默认布局效果

MultiDiversion组件基于默认断点区间,内置了一套多设备布局效果,如下图所示

sm

md

lg

27.png

28.png

29.png

MultiDiversion父组件 API

1. Attribute

属性

说明

类型

可选值

默认值

direction

设置组件的排列方向

String

horizontal:横向排列

vertical:纵向排列

xs:vertical

sm:vertical

md:horizontal

lg:horizontal

xl:horizontal

splitLine

设置是否显示子组件分割线

Boolean

true

false

false

splitLineMode

设置子组件分割线的类型

String

solid:实线

dashed:虚线

dotted:点线

dotted

MultiDiversionItem子组件 API

属性

说明

类型

可选值

默认值

name

子组件的唯一标识名称(必填)

String

diversionCols

设置子组件占据的栅格列数,最大值为12。

子组件横向排列且栅格总和大于12时,按照栅格比例分配父容器宽度。

String / Number

12

diversionGap

设置子组件内容的左右内边距和

String / Number

0

推荐使用方式(以Vue3为例)

// MultiDiversion/index.vue 
<template> 
  <MultiDiversionVue :direction="diversionDirection"> 
    <DiversionItemVue name="firstContent" > 
      // 内容区1 
    </DiversionItemVue> 
    <DiversionItemVue name="secondContent" > 
      // 内容区2 
    </DiversionItemVue> 
  </MultiDiversionVue> 
</template> 
 
<script setup> 
import { ref, onUnmounted } from "vue"; 
import { MultiDiversionVue, DiversionItemVue } from "@hadss/web_adaptive_layout_vue3"; 
import { breakpointManager } from "../../utils/breakpointInit"; 
 
const diversionDirection = ref("vertical"); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  // 传入不同断点下的diversion属性值,根据当前断点返回对应的值 
  diversionDirection.value = breakpointManager.useBreakpointValue({ 
    xs: "vertical", 
    sm: "vertical", 
    md: "horizontal", 
    lg: "horizontal",  
    xl: "horizontal", 
  }); 
}); 
onUnmounted(() => { 
  // 取消订阅断点变化 
  unsubscribe(); 
  // 销毁实例,移除监听器,清空回调函数集合 
  breakpointManager.destroy(); 
}); 
</script>

5.2 场景案例

实现效果

注意:实现效果中的红色框仅表示组件位置,不代表对应组件的边框。

sm

md

lg

30.png

31.png

32.png

关键代码(以vue3为例)

  • 子组件name属性必填,且一个项目中子组件name属性不能重复。
  • direction为类挪移组件里两个组件的排列方式,"horizontal":横向排列,"vertical":纵向排列。结合breakpointManager断点管理即可实现在不同设备上展示不同的布局方式。
  • diversionCols为类挪移子组件里两个组件所占的比例,类挪移组件默认宽度为12。子组件设置大于12时会占满整个类挪移组件的宽度。

更多属性及设置参考 类挪移布局组件multidiversion

具体代码如下:

// web_advanced_ui_sample\vue3_sample\src\components\PageHeader\index.vue 
<template> 
  <div class="home-header"> 
    <MultiDiversionVue :direction="multiDiversionDirection"> 
      <DiversionItemVue name="firstTitle"  
                        :diversionCols="tabBarCols"  
                        :diversionGap="barGap"> 
        <div class="top-tab-bar"> 
          <span class="top-tab-bar-text-selected">华为</span> 
          <span class="top-tab-bar-text">AITO汽车</span> 
          <span class="top-tab-bar-text">华为智选</span> 
          <span class="top-tab-bar-text">生态周边</span> 
        </div> 
      </DiversionItemVue> 
      <DiversionItemVue name="secondTitle"  
                        :diversionCols="searchBarCols"  
                        :diversionGap="barGap"> 
        <div class="search-bar"> 
          <input type="search-bar-text"  
                 class="search-bar-input"  
                 placeholder="搜索..." /> 
          <img class="search-bar-image"  
               src="../../assets/line_viewfinder.svg" /> 
          <img class="search-bar-image"  
               src="../../assets/msg_big.png" /> 
        </div> 
      </DiversionItemVue> 
    </MultiDiversionVue> 
  </div> 
</template> 
 
<script setup> 
import { onUnmounted, ref } from "vue"; 
import { MultiDiversionVue, DiversionItemVue } from "@hadss/web_adaptive_layout_vue3"; 
import { breakpointManager } from "../../utils/breakpointInit"; 
 
const multiDiversionDirection = ref("vertical"); 
const tabBarCols = ref("7"); 
const searchBarCols = ref("5"); 
const barGap = ref("10px"); 
// 订阅断点变化 
const unsubscribe = breakpointManager.subscribeToBreakpoint(() => { 
  multiDiversionDirection.value = breakpointManager.useBreakpointValue({ 
    xs: "vertical", 
    sm: "vertical", 
    md: "horizontal", 
    lg: "horizontal", 
    xl: "horizontal", 
  }); 
  tabBarCols.value = breakpointManager.useBreakpointValue({ 
    xs: "12", 
    sm: "12", 
    md: "7", 
    lg: "8", 
    xl: "8", 
  }); 
  searchBarCols.value = breakpointManager.useBreakpointValue({ 
    xs: "12", 
    sm: "12", 
    md: "5", 
    lg: "4", 
    xl: "8", 
  }); 
}); 
// 取消订阅,销毁断点实例 
onUnmounted(() => { 
  unsubscribe(); 
  breakpointManager.destroy(); 
}) 
 
</script> 
<style lang="less" scoped> 
@import './index.less'; 
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值