Mobile Layout
To further reduce development costs, we have built-in layout functionality through WinJS plugins. With simple configuration, you can have a complete layout including common mobile H5 elements: top title bar, middle content area, and bottom tab bar. This allows users to focus on business logic without worrying about layout implementation.
Note
This solution is only compatible with Vue 3. Since it depends on some Vant components at the underlying level, you need to install Vant when using this plugin.
Setup
- Install the plugin
$ npm add @winner-fed/plugin-mobile-layout -D
$ yarn add @winner-fed/plugin-mobile-layout -D
$ pnpm add @winner-fed/plugin-mobile-layout -D
$ bun add @winner-fed/plugin-mobile-layout -D
- Add dependency in
package.json
{
"dependencies": {
"vant": "^4.6.5"
}
}
- Enable the plugin in the
.winrc
configuration file
import { defineConfig } from 'win';
export default defineConfig({
plugins: [require.resolve('@winner-fed/plugin-mobile-layout')],
/**
* @name mobileLayout plugin
* @doc https://winjs-dev.github.io/winjs-docs/plugins/mobilelayout.html
*/
mobileLayout: {}
});
Configuration
Runtime Configuration
You can configure the bottom navigation tab bar, default title for all pages, page titles, and page header navigation bar in src/app.(j|t)[s]x
.
By exporting the mobileLayout
object, it will be passed as configuration to the WinJS mobile layout component. As shown below:
// app.ts
export const mobileLayout = {
tabBar,
navBar,
documentTitle: 'demo',
titleList
};
Property | Type | Required | Description |
---|---|---|---|
tabBar | TabBarProps | No | Define bottom navigation tab bar |
navBar | _NavBarProps | No | Define page header navigation bar |
documentTitle | string | No | Define default title for all pages |
titleList | TitleListItem[] | No | Define page titles |
Define Bottom Navigation Tab Bar
The TabBarProps
type for tabBar
is defined as follows:
Property | Type | Required | Description |
---|---|---|---|
color | string | Yes | Default text color of navigation tabs |
selectedColor | string | Yes | Text color of navigation tabs when selected |
backgroundColor | string | Yes | Background color of navigation tabs |
tabBarItem | TabBarItem[] | Yes | List of navigation tabs |
tabBeforeChange | (navigator: any, name: number | string) => void | Promise<boolean> | No | Callback before tab switch, return false to prevent switch, supports Promise |
tabChange | (navigator: any, name: number | string) => void | No | Triggered when tab is switched |
The TabBarItem
type for tabBar.tabBarItem
is defined as follows:
Property | Type | Required | Description |
---|---|---|---|
pagePath | string | Yes | Page path, must be defined in pages first |
text | string | No | Text of navigation tab |
iconPath | string | No | Icon path of navigation tab |
selectedIconPath | string | No | Icon path when navigation tab is selected |
dot | boolean | No | Whether to show red dot on top-right of icon, default false |
badge | string | No | Number displayed on top-right of navigation tab icon (badge) |
onPress | (navigator: any, data?: TabBarItem) => void | Promise<boolean> | No | Navigation tab click callback |
title | string | No | Page title |
icon | object | string | No | Custom navigation tab |
selectedIcon | object | string | No | Custom selected navigation tab |
Define Page Header Navigation Bar
The NavBarProps
type for navBar
is defined as follows:
Property | Description | Type | Default |
---|---|---|---|
mode | Style mode | string | 'dark' 'dark', 'light' |
icon | Icon in the left return area of header navigation | object | string | Pages not defined in tabsBar will have default left return icon |
leftContent | Content on the right side of left return area | any | None |
rightContent | Right content of header navigation | any | None |
leftText | Left return text of header navigation | string | None |
onLeftClick | Click callback for left return area | (navigator) => void | Default event with left return icon is to go back to previous page |
hideNavBar | Hide NavBar, NavBar is shown by default | boolean | false |
pageTitle | Page title | string | None, highest priority |
navList | Set navbar for specific pages separately | NarBarListItem | None |
The NavBarListItem
type for navList
is defined as follows:
Property | Type | Default | Description |
---|---|---|---|
pagePath | string | None | Page path, must be defined in pages first |
navBar | NavBarProps | None | NavBar for current route |
Define Page Titles
The TitleListItem[]
type for titleList
is defined as follows:
Property | Type | Required | Description |
---|---|---|---|
pagePath | string | Yes | Page path, must be defined in pages first |
title | string | No | Page title |
Define Default Title for All Pages
export const mobileLayout = {
documentTitle: 'Default Title',
};
Page Title Setting Priority
titleList
's title
> tabBar
's list
's title
> documentTitle
.
Complete Example
Here's an example:
// Custom TabarIcon
import TabbarIcon from '@/components/TabbarIcon';
import type {
NavBarListItem,
NavBarProps,
TabBarItem,
TabBarProps,
TitleListItem,
MobileLayoutProps
} from 'winjs';
const titleList: TitleListItem[] = [
{
pagePath: '/',
title: 'Registration',
},
{
pagePath: '/signIn',
title: 'Sign In',
},
{
pagePath: '/query',
title: 'Query',
},
{
pagePath: '/other',
title: 'Other',
},
];
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: 'Registration',
icon: <TabbarIcon icon - name = "icon-sign-up" / >,
selectedIcon: <TabbarIcon icon - name = "icon-sign-up" / >,
title: 'Registration',
},
{
pagePath: '/signIn',
text: 'Sign In',
icon: <TabbarIcon icon - name = "icon-sign-in" / >,
selectedIcon: <TabbarIcon icon - name = "icon-sign-in" / >,
title: 'Sign In'
},
{
pagePath: '/query',
text: 'Query',
icon: <TabbarIcon icon - name = "icon-query" / >,
selectedIcon: <TabbarIcon icon - name = "icon-query" / >,
title: 'Query'
},
{
pagePath: '/other',
text: 'Other',
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,
};
<!--TabbarIcon.vue-->
<script setup lang="ts">
defineProps({
iconName: {
type: String,
required: true
}
});
</script>
<template>
<i class="icon" :class="iconName"></i>
</template>
Detailed property configuration description:
export interface TitleListItem {
// Page route
pagePath: string;
// Title
title: string;
}
export interface TabBarItem {
pagePath: string;
// Tab bar bottom text
text?: string;
iconPath?: string;
selectedIconPath?: string;
// Whether to show red dot on top-right of icon
dot?: boolean;
// Content of badge on top-right of icon
badge?: number | string;
title?: string;
icon?: string;
selectedIcon?: string;
onPress?: (navigator: any, data?: TabBarItem) => void | Promise<boolean>;
}
export interface TabBarProps {
// Whether to fix at bottom
fixed?: boolean;
// Color of unselected tabs
color?: string;
// Color of selected tabs
selectedColor?: string;
tabBarItem?: TabBarItem[];
// Callback before tab switch, return false to prevent switch, supports 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[];
}