跳转到内容

移动端布局

NPM Version

为了进一步降低研发成本,我们将布局利用 WinJS 插件的方式内置,只需通过简单的配置即可拥有布局,包括移动端H5常见的顶部标题栏,中间内容区域以及底部的标签栏。从而做到使用者无需关心布局。

说明

此方案只适用于 Vue3。由于底层依赖了 Vant 的部分组件,因此在使用此插件时,需要安装 Vant。

启用方式

  1. 安装插件
bash
$ npm add @winner-fed/plugin-mobile-layout -D
bash
$ yarn add @winner-fed/plugin-mobile-layout -D
bash
$ pnpm add @winner-fed/plugin-mobile-layout -D
bash
$ bun add @winner-fed/plugin-mobile-layout -D
  1. package.json 中引入依赖
json
{
  "dependencies": {
    "vant": "^4.6.5"
  }
}
  1. 在配置文件中 .winrc 中开启该功能
ts
import { defineConfig } from 'win';

export default defineConfig({
  plugins: [require.resolve('@winner-fed/plugin-mobile-layout')],
  /**
   * @name mobileLayout 插件
   * @doc https://winjs-dev.github.io/winjs-docs/plugins/mobilelayout.html
   */
  mobileLayout: {}
});

配置

运行时配置

可以在 src/app.(j|t)[s]x 中配置页面底部导航标签栏、所有页面的默认 title、页面的 title、页面头部导航栏。

通过 export mobileLayout 对象将作为配置传递给 WinJS 移动端布局组件。如下所示:

ts
// app.ts
export const mobileLayout = {
  tabBar,
  navBar,
  documentTitle: 'demo',
  titleList
};
属性类型必填描述
tabBarTabBarProps定义页面底部导航标签栏
navBar_NavBarProps定义页面头部导航栏
documentTitlestring定义所有页面的默认标题
titleListTitleListItem[]定义页面的标题

定义页面底部导航标签栏

tabBar 的类型 TabBarProps 定义如下:

属性类型必填描述
colorstring导航标签的文字默认颜色
selectedColorstring导航标签的文字选中时的颜色
backgroundColorstring导航标签的背景色
tabBarItemTabBarItem[]导航标签的列表
tabBeforeChange(navigator: any, name: number | string) => void | Promise<boolean>切换标签前的回调函数,返回 false 可阻止切换,支持返回 Promise
tabChange(navigator: any, name: number | string) => void切换标签时触发

tabBar.tabBarItem 的类型 TabBarItem 定义如下:

属性类型必填说明
pagePathstring页面路径,必须在 pages 中先定义
textstring导航标签的文字
iconPathstring导航标签图标路径
selectedIconPathstring导航标签选中时的图标路径
dotboolean是否显示图标右上角小红点,默认 false
badgestring导航标签图标右上角显示数值 (微标数)
onPress(navigator: any, data?: TabBarItem) => void | Promise<boolean>导航标签点击回调
titlestring页面标题
iconobject | string自定义导航标签
selectedIconobject | string自定义选中的导航标签

定义页面头部导航栏

navBar 的类型 NavBarProps 定义如下:

属性说明类型默认值
mode风格模式string'dark' 'dark', 'light'
icon头部导航左侧,返回区域的图标object | string不在 tabsBar 中定义的页面,会有默认左返回图标
leftContent头部导航左侧的返回区域的右侧内容any
rightContent头部导航右侧内容any
leftText头部导航左侧的返回文案string
onLeftClick头部导航左侧的返回区域点击回调(navigator) => void有左侧回退图标的默认事件是返回上一页
hideNavBar隐藏 NavBar,默认有 NarBarbooleanfalse
pageTitle页面标题string无,优先级最高
navList单独设置某些页面的 navbarNarBarListItem

navList 的类型 NavBarListItem 定义如下:

属性类型默认值说明
pagePathstring页面路径,必须在 pages 中先定义
navBarNavBarProps当前路由的 navBar

定义页面的标题

titleList 的类型 TitleListItem[] 定义如下:

属性类型必填说明
pagePathstring页面路径,必须在 pages 中先定义
titlestring页面标题

定义所有页面的默认标题

ts
export const mobileLayout = {
  documentTitle: '默认标题',
};

页面标题的设置优先级

titleListtitle> tabBarlisttitle > documentTitle

完整示例

举个例子,如下所示:

ts
// 自定义 TabarIcon
import TabbarIcon from '@/components/TabbarIcon';

import type {
  NavBarListItem,
  NavBarProps,
  TabBarItem,
  TabBarProps,
  TitleListItem,
  MobileLayoutProps
} from 'winjs';

const titleList: TitleListItem[] = [
  {
    pagePath: '/',
    title: '报名',
  },
  {
    pagePath: '/signIn',
    title: '签到',
  },
  {
    pagePath: '/query',
    title: '查询',
  },
  {
    pagePath: '/other',
    title: '其他',
  },
];

const navList: NavBarListItem = [
  {
    pagePath: '/',
    navBar: {},
  },
  {
    pagePath: '/signIn',
    navBar: {},
  },
  {
    pagePath: '/query',
    navBar: {},
  },
  {
    pagePath: '/other',
    navBar: {},
  },
]
const navBar: NavBarProps = {
  navList,
  fixed: true,
  mode: 'light',
  hideNavBar: true
};

const tabList: TabBarItem[] = [
  {
    pagePath: '/',
    text: '报名',
    icon: <TabbarIcon icon - name = "icon-sign-up" / >,
    selectedIcon: <TabbarIcon icon - name = "icon-sign-up" / >,
    title: '报名',
  },
  {
    pagePath: '/signIn',
    text: '签到',
    icon: <TabbarIcon icon - name = "icon-sign-in" / >,
    selectedIcon: <TabbarIcon icon - name = "icon-sign-in" / >,
    title: '签到'
  },
  {
    pagePath: '/query',
    text: '查询',
    icon: <TabbarIcon icon - name = "icon-query" / >,
    selectedIcon: <TabbarIcon icon - name = "icon-query" / >,
    title: '查询'
  },
  {
    pagePath: '/other',
    text: '其他',
    icon: <TabbarIcon icon - name = "icon-other" / >,
    selectedIcon: <TabbarIcon icon - name = "icon-other" / >,
    title: 'other'
  },
];
const tabBar: TabBarProps = {
  color: `#929292`,
  selectedColor: '#00b38a',
  tabBarItem: tabList,
};

export const mobileLayout: MobileLayoutProps = {
  theme: 'light',
  documentTitle: 'Demo',
  navBar,
  titleList,
  tabBar,
};
vue
<!--TabbarIcon.vue-->
<script setup lang="ts">
defineProps({
  iconName: {
    type: String,
    required: true
  }
});

</script>

<template>
  <i class="icon" :class="iconName"></i>
</template>

具体属性配置说明:

ts
export interface TitleListItem {
  // 页面路由
  pagePath: string;
  // 标题
  title: string;
}

export interface TabBarItem {
  pagePath: string;
  // 标签栏底部文字
  text?: string;
  iconPath?: string;
  selectedIconPath?: string;
  // 是否显示图标右上角小红点
  dot?: boolean;
  // 图标右上角徽标的内容
  badge?: number | string;
  title?: string;
  icon?: string;
  selectedIcon?: string;
  onPress?: (navigator: any, data?: TabBarItem) => void | Promise<boolean>;
}

export interface TabBarProps {
  // 是否固定在底部
  fixed?: boolean;
  // 未选中标签的颜色
  color?: string;
  // 选中标签的颜色
  selectedColor?: string;
  tabBarItem?: TabBarItem[];
  // 切换标签前的回调函数,返回 false 可阻止切换,支持返回 Promise
  tabBeforeChange?: (
    navigator: any,
    name: number | string,
  ) => void | Promise<boolean>;
  tabChange?: (navigator: any, name: number | string) => void;
}

export interface _NavBarProps {
  mode?: 'dark' | 'light';
  icon?: object | string;
  leftText?: string;
  leftContent?: any;
  rightContent?: any;
  onLeftClick?: (navigator: any) => void;
  hideNavBar?: boolean;
  pageTitle?: string;
}

export interface NavBarListItem {
  pagePath: string;
  navBar?: _NavBarProps;
}

export interface NavBarProps extends _NavBarProps {
  fixed?: boolean;
  navList?: NavBarListItem[];
}

export interface TitleItems {
  pagePath: string;
  title?: string;
}

export interface MobileLayoutProps {
  theme?: 'dark' | 'light';
  tabBar?: TabBarProps;
  navBar?: NavBarProps;
  documentTitle?: string;
  titleList?: TitleItems[];
}

基于 MIT 许可发布