Menu菜单
在一个临时的面板上显示一组操作。
规则
- 至少包含 2 个以上的菜单项。
- 不应该被当做主要导航方式。
代码演示
菜单
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'demo-menu-basic',
template: `
<div [ngClass]="[show ? 'menu-active' : '']">
<div>
<Navbar [leftContent]="'Menu'" [icon]="icon" (onLeftClick)="handleClick($event)" class="top-nav-bar">
Here is title
</Navbar>
</div>
<Menu
*ngIf="show && initData"
class="foo-menu"
[data]="initData"
[value]="['1', '3']"
(onChange)="onChange($event)"
[height]="menuHeight"
>
</Menu>
<div
*ngIf="show && !initData"
style="width: 100%; height: 200px; display: flex; justify-content: center; align-items: center"
>
<ActivityIndicator [size]="'large'"></ActivityIndicator>
</div>
<div *ngIf="show" class="menu-mask1" (click)="onMaskClick()"></div>
</div>
<ng-template #icon>
<img
src="https://gw.alipayobjects.com/zos/rmsportal/iXVHARNNlmdCGnwWxQPH.svg"
class="am-icon am-icon-md"
alt=""
/>
</ng-template>
`,
styles: [
`
.foo-menu {
position: relative;
z-index: 1000 !important;
}
.menu-active .top-nav-bar {
z-index: 80;
}
.top-nav-bar {
position: relative;
background-color: #008ae6;
color: #fff;
}
.menu-mask1 {
content: ' ';
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.4;
z-index: 79;
}
`
],
encapsulation: ViewEncapsulation.None
})
export class DemoMenuBasicComponent {
initData: Array<any>;
show: boolean = false;
menuHeight: number = document.documentElement.clientHeight * 0.6;
dataMenu: Array<any> = [
{
value: '1',
label: 'Food',
children: [
{
label: 'All Foods',
value: '1',
disabled: false
},
{
label: 'Chinese Food',
value: '2'
},
{
label: 'Hot Pot',
value: '3'
},
{
label: 'Buffet',
value: '4'
},
{
label: 'Fast Food',
value: '5'
},
{
label: 'Snack',
value: '6'
},
{
label: 'Bread',
value: '7'
},
{
label: 'Fruit',
value: '8'
},
{
label: 'Noodle',
value: '9'
},
{
label: 'Leisure Food',
value: '10'
}
]
},
{
value: '2',
label: 'Supermarket',
children: [
{
label: 'All Supermarkets',
value: '1'
},
{
label: 'Supermarket',
value: '2',
disabled: true
},
{
label: 'C-Store',
value: '3'
},
{
label: 'Personal Care',
value: '4'
}
]
},
{
value: '3',
label: 'Extra',
isLeaf: true,
children: [
{
label: 'you can not see',
value: '1'
}
]
}
];
onChange(value) {
let label = '';
this.dataMenu.forEach(dataItem => {
if (dataItem.value === value[0]) {
label = dataItem.label;
if (dataItem.children && value[1]) {
for (let i = 0; i < dataItem.children.length; i++) {
const cItem = dataItem.children[i];
if (cItem.value === value[1]) {
label += cItem.label;
}
}
}
}
});
console.log(label);
}
handleClick(e) {
e.preventDefault();
this.show = !this.show;
if (!this.initData) {
setTimeout(() => {
this.initData = this.dataMenu;
}, 500);
}
}
onMaskClick() {
this.show = false;
}
}
单级菜单
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'demo-menu-singleSelect',
template: `
<div [ngClass]="[show ? 'single-menu-active' : '']">
<div>
<Navbar class="single-top-nav-bar" [leftContent]="'Menu'" (onLeftClick)="handleClick($event)">
Here is title
</Navbar>
</div>
<Menu
*ngIf="show && initData"
class="single-foo-menu"
[data]="initData"
[value]="['1']"
[level]="1"
(onChange)="onChange($event)"
[height]="menuHeight"
>
</Menu>
<div
*ngIf="show && !initData"
style="width: 100% ;height: 200px; display: flex; justify-content: center; align-items: center"
>
<ActivityIndicator [size]="'large'"></ActivityIndicator>
</div>
<div *ngIf="show" class="menu-mask2" (click)="onMaskClick()"></div>
</div>
`,
styles: [
`
.single-foo-menu {
position: absolute;
z-index: 90 !important;
width: 100%;
}
.single-menu-active .single-top-nav-bar {
z-index: 90;
}
.single-top-nav-bar {
position: relative;
background-color: #008ae6;
color: #fff;
}
.menu-mask2 {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.4;
z-index: 89;
}
`
],
encapsulation: ViewEncapsulation.None
})
export class DemoMenuSingleSelectComponent {
initData: Array<any>;
show: boolean = false;
menuHeight: number = document.documentElement.clientHeight * 0.6;
data: Array<any> = [
{
value: '1',
label: 'Food'
},
{
value: '2',
label: 'Supermarket'
},
{
value: '3',
label: 'Extra',
isLeaf: true
}
];
onChange(value) {
console.log(value);
}
handleClick(e) {
e.preventDefault();
this.show = !this.show;
if (!this.initData) {
setTimeout(() => {
this.initData = this.data;
}, 500);
}
}
onMaskClick() {
this.show = false;
}
}
菜单多选
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'demo-menu-multiSelect',
template: `
<div [ngClass]="[show ? 'multi-menu-active' : '']">
<div>
<Navbar [leftContent]="'Menu'" (onLeftClick)="handleClick($event)" class="multi-top-nav-bar">
Here is title
</Navbar>
</div>
<Menu
*ngIf="show && initData"
class="multi-foo-menu"
[data]="initData"
[value]="['1', ['3', '4']]"
[multiSelect]="true"
(onChange)="onChange($event)"
(onOk)="onOk($event)"
(onCancel)="onCancel()"
[height]="menuHeight"
>
</Menu>
<div
*ngIf="show && !initData"
style="width: 100% ;height: 200px; display: flex; justify-content: center; align-items: center"
>
<ActivityIndicator [size]="'large'"></ActivityIndicator>
</div>
<div *ngIf="show" class="menu-mask3" (click)="onMaskClick()"></div>
</div>
`,
styles: [
`
.multi-foo-menu {
position: absolute;
z-index: 80 !important;
width: 100%;
}
.multi-menu-active .multi-top-nav-bar {
z-index: 80;
}
.multi-top-nav-bar {
position: relative;
background-color: #008ae6;
color: #fff;
}
.menu-mask3 {
content: ' ';
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.4;
z-index: 79;
}
`
],
encapsulation: ViewEncapsulation.None
})
export class DemoMenuMultiSelectComponent {
initData: Array<any>;
show: boolean = false;
menuHeight: number = document.documentElement.clientHeight * 0.6;
dataMenu: Array<any> = [
{
value: '1',
label: 'Food',
children: [
{
label: 'All Foods',
value: '1',
disabled: false
},
{
label: 'Chinese Food',
value: '2'
},
{
label: 'Hot Pot',
value: '3'
},
{
label: 'Buffet',
value: '4'
},
{
label: 'Fast Food',
value: '5'
},
{
label: 'Snack',
value: '6'
},
{
label: 'Bread',
value: '7'
},
{
label: 'Fruit',
value: '8'
},
{
label: 'Noodle',
value: '9'
},
{
label: 'Leisure Food',
value: '10'
}
]
},
{
value: '2',
label: 'Supermarket',
children: [
{
label: 'All Supermarkets',
value: '1'
},
{
label: 'Supermarket',
value: '2',
disabled: true
},
{
label: 'C-Store',
value: '3'
},
{
label: 'Personal Care',
value: '4'
}
]
},
{
value: '3',
label: 'Extra',
isLeaf: true,
children: [
{
label: 'you can not see',
value: '1'
}
]
}
];
onChange(value) {
console.log(value);
}
handleClick(e) {
e.preventDefault();
this.show = !this.show;
if (!this.initData) {
setTimeout(() => {
this.initData = this.dataMenu;
}, 500);
}
}
onMaskClick() {
this.show = false;
}
onOk(value) {
console.log(value);
this.onCancel();
}
onCancel() {
this.show = false;
}
}
单级菜单多选
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'demo-menu-singleMulti',
template: `
<div [ngClass]="[show ? 'single-multi-menu-active' : '']">
<div>
<Navbar [leftContent]="'Menu'" (onLeftClick)="handleClick($event)" class="single-multi-top-nav-bar">
Here is title
</Navbar>
</div>
<Menu
*ngIf="show && initData"
class="single-multi-foo-menu"
[data]="initData"
[value]="['1']"
[level]="1"
[multiSelect]="true"
(onChange)="onChange($event)"
(onOk)="onOk($event)"
(onCancel)="onCancel()"
[height]="menuHeight"
>
</Menu>
<div
*ngIf="show && !initData"
style="width: 100% ;height: 200px; display: flex; justify-content: center; align-items: center"
>
<ActivityIndicator [size]="'large'"></ActivityIndicator>
</div>
<div *ngIf="show" class="menu-mask4" (click)="onMaskClick()"></div>
</div>
`,
styles: [
`
.single-multi-foo-menu {
position: absolute;
z-index: 70 !important;
width: 100%;
}
.single-multi-menu-active .single-multi-top-nav-bar {
z-index: 80;
}
.single-multi-top-nav-bar {
position: relative;
background-color: #008ae6;
color: #fff;
}
.menu-mask4 {
content: ' ';
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.4;
z-index: 69;
}
`
],
encapsulation: ViewEncapsulation.None
})
export class DemoMenuSingleMultiComponent {
initData: Array<any>;
show: boolean = false;
menuHeight: number = document.documentElement.clientHeight * 0.6;
data: Array<any> = [
{
value: '1',
label: 'Food'
},
{
value: '2',
label: 'Supermarket'
},
{
value: '3',
label: 'Extra',
isLeaf: true
}
];
onChange(value) {
console.log(value);
}
handleClick(e) {
e.preventDefault();
this.show = !this.show;
if (!this.initData) {
setTimeout(() => {
this.initData = this.data;
}, 500);
}
}
onMaskClick() {
this.show = false;
}
onOk(value) {
console.log(value);
this.onCancel();
}
onCancel() {
console.log('onCancel');
this.show = false;
}
}
API
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[data] | 数据(isLeaf 设置后 children 无效) | Array<{label: string, value, disabled?, children<data>?, isLeaf?}> | [] |
[level] | 菜单级数 | 1 | 2 | 2 |
[value] | 初始值,一级和二级筛选数据的value 组成的数组。在多选状态下,如果为二级菜单,则数组的第一个元素为一级菜单的选项,数组的第二个元素是一个数组,里面包含了二级菜单的多选项;如果为一级菜单,则数组所有元素都是多选项 | Array | - |
[height] | 筛选组件的高度 | number | document.documentElement.clientHeight / 2 |
[multiSelect] | 是否支持菜单多选 | boolean | false |
(onChange) | 选择后的回调函数 | EventEmitter<object> | - |
(onOk) | 多选状态下确认按钮回调 | EventEmitter<object> | - |
(onCancel) | 多选状态下取消按钮回调 | EventEmitter<void> | - |