• Menu菜单
    • 规则
  • 代码演示
  • API

    Menu菜单

    在一个临时的面板上显示一组操作。

    规则

    • 至少包含 2 个以上的菜单项。
    • 不应该被当做主要导航方式。

    代码演示

    菜单

    1. import { Component, ViewEncapsulation } from '@angular/core';
    2. @Component({
    3. selector: 'demo-menu-basic',
    4. template: `
    5. <div [ngClass]="[show ? 'menu-active' : '']">
    6. <div>
    7. <Navbar [leftContent]="'Menu'"
    8. [icon]="icon"
    9. (onLeftClick)="handleClick($event)"
    10. class="top-nav-bar">
    11. Here is title
    12. </Navbar>
    13. </div>
    14. <Menu *ngIf="show && initData"
    15. class="foo-menu"
    16. [data]="initData"
    17. [value]="['1', '3']"
    18. (onChange)="onChange($event)"
    19. [height]="menuHeight">
    20. </Menu>
    21. <div *ngIf="show && !initData" style="width: 100%; height: 200px; display: flex; justify-content: center; align-items: center">
    22. <ActivityIndicator [size]="'large'"></ActivityIndicator>
    23. </div>
    24. <div *ngIf="show" class="menu-mask1" (click)="onMaskClick()"></div>
    25. </div>
    26. <ng-template #icon>
    27. <img src="https://gw.alipayobjects.com/zos/rmsportal/iXVHARNNlmdCGnwWxQPH.svg" class="am-icon am-icon-md" alt=""/>
    28. </ng-template>
    29. `,
    30. styles: [
    31. `
    32. .foo-menu {
    33. position: relative;
    34. z-index: 1000 !important;
    35. }
    36. .menu-active .top-nav-bar {
    37. z-index: 80;
    38. }
    39. .top-nav-bar {
    40. position: relative;
    41. background-color: #008ae6;
    42. color: #fff;
    43. }
    44. .menu-mask1 {
    45. content: ' ';
    46. position: absolute;
    47. top: 0;
    48. width: 100%;
    49. height: 100%;
    50. background-color: #000;
    51. opacity: 0.4;
    52. z-index: 79;
    53. }
    54. `
    55. ],
    56. encapsulation: ViewEncapsulation.None
    57. })
    58. export class DemoMenuBasicComponent {
    59. initData: Array<any>;
    60. show: boolean = false;
    61. menuHeight: number = document.documentElement.clientHeight * 0.6;
    62. dataMenu: Array<any> = [
    63. {
    64. value: '1',
    65. label: 'Food',
    66. children: [
    67. {
    68. label: 'All Foods',
    69. value: '1',
    70. disabled: false
    71. },
    72. {
    73. label: 'Chinese Food',
    74. value: '2'
    75. },
    76. {
    77. label: 'Hot Pot',
    78. value: '3'
    79. },
    80. {
    81. label: 'Buffet',
    82. value: '4'
    83. },
    84. {
    85. label: 'Fast Food',
    86. value: '5'
    87. },
    88. {
    89. label: 'Snack',
    90. value: '6'
    91. },
    92. {
    93. label: 'Bread',
    94. value: '7'
    95. },
    96. {
    97. label: 'Fruit',
    98. value: '8'
    99. },
    100. {
    101. label: 'Noodle',
    102. value: '9'
    103. },
    104. {
    105. label: 'Leisure Food',
    106. value: '10'
    107. }
    108. ]
    109. },
    110. {
    111. value: '2',
    112. label: 'Supermarket',
    113. children: [
    114. {
    115. label: 'All Supermarkets',
    116. value: '1'
    117. },
    118. {
    119. label: 'Supermarket',
    120. value: '2',
    121. disabled: true
    122. },
    123. {
    124. label: 'C-Store',
    125. value: '3'
    126. },
    127. {
    128. label: 'Personal Care',
    129. value: '4'
    130. }
    131. ]
    132. },
    133. {
    134. value: '3',
    135. label: 'Extra',
    136. isLeaf: true,
    137. children: [
    138. {
    139. label: 'you can not see',
    140. value: '1'
    141. }
    142. ]
    143. }
    144. ];
    145. onChange(value) {
    146. let label = '';
    147. this.dataMenu.forEach(dataItem => {
    148. if (dataItem.value === value[0]) {
    149. label = dataItem.label;
    150. if (dataItem.children && value[1]) {
    151. for (let i = 0; i < dataItem.children.length; i++) {
    152. const cItem = dataItem.children[i];
    153. if (cItem.value === value[1]) {
    154. label += cItem.label;
    155. }
    156. }
    157. }
    158. }
    159. });
    160. console.log(label);
    161. }
    162. handleClick(e) {
    163. e.preventDefault();
    164. this.show = !this.show;
    165. if (!this.initData) {
    166. setTimeout(() => {
    167. this.initData = this.dataMenu;
    168. }, 500);
    169. }
    170. }
    171. onMaskClick() {
    172. this.show = false;
    173. }
    174. }

    单级菜单

    1. import { Component, ViewEncapsulation } from '@angular/core';
    2. @Component({
    3. selector: 'demo-menu-singleSelect',
    4. template: `
    5. <div [ngClass]="[show ? 'single-menu-active' : '']">
    6. <div>
    7. <Navbar class="single-top-nav-bar"
    8. [leftContent]="'Menu'"
    9. (onLeftClick)="handleClick($event)"
    10. >
    11. Here is title
    12. </Navbar>
    13. </div>
    14. <Menu *ngIf="show && initData"
    15. class="single-foo-menu"
    16. [data]="initData"
    17. [value]="['1']"
    18. [level]="1"
    19. (onChange)="onChange($event)"
    20. [height]="menuHeight">
    21. </Menu>
    22. <div *ngIf="show && !initData" style="width: 100% ;height: 200px; display: flex; justify-content: center; align-items: center">
    23. <ActivityIndicator [size]="'large'"></ActivityIndicator>
    24. </div>
    25. <div *ngIf="show" class="menu-mask2" (click)="onMaskClick()"></div>
    26. </div>
    27. `,
    28. styles: [
    29. `
    30. .single-foo-menu {
    31. position: absolute;
    32. z-index: 90 !important;
    33. width: 100%;
    34. }
    35. .single-menu-active .single-top-nav-bar {
    36. z-index: 90;
    37. }
    38. .single-top-nav-bar {
    39. position: relative;
    40. background-color: #008ae6;
    41. color: #fff;
    42. }
    43. .menu-mask2 {
    44. position: absolute;
    45. top: 0;
    46. width: 100%;
    47. height: 100%;
    48. background-color: #000;
    49. opacity: 0.4;
    50. z-index: 89;
    51. }
    52. `
    53. ],
    54. encapsulation: ViewEncapsulation.None
    55. })
    56. export class DemoMenuSingleSelectComponent {
    57. initData: Array<any>;
    58. show: boolean = false;
    59. menuHeight: number = document.documentElement.clientHeight * 0.6;
    60. data: Array<any> = [
    61. {
    62. value: '1',
    63. label: 'Food'
    64. },
    65. {
    66. value: '2',
    67. label: 'Supermarket'
    68. },
    69. {
    70. value: '3',
    71. label: 'Extra',
    72. isLeaf: true
    73. }
    74. ];
    75. onChange(value) {
    76. console.log(value);
    77. }
    78. handleClick(e) {
    79. e.preventDefault();
    80. this.show = !this.show;
    81. if (!this.initData) {
    82. setTimeout(() => {
    83. this.initData = this.data;
    84. }, 500);
    85. }
    86. }
    87. onMaskClick() {
    88. this.show = false;
    89. }
    90. }

    菜单多选

    1. import { Component, ViewEncapsulation } from '@angular/core';
    2. @Component({
    3. selector: 'demo-menu-multiSelect',
    4. template: `
    5. <div [ngClass]="[show ? 'multi-menu-active' : '']">
    6. <div>
    7. <Navbar [leftContent]="'Menu'"
    8. (onLeftClick)="handleClick($event)"
    9. class="multi-top-nav-bar">
    10. Here is title
    11. </Navbar>
    12. </div>
    13. <Menu *ngIf="show && initData"
    14. class="multi-foo-menu"
    15. [data]="initData"
    16. [value]="['1', ['3', '4']]"
    17. [multiSelect]="true"
    18. (onChange)="onChange($event)"
    19. (onOk)="onOk($event)"
    20. (onCancel)="onCancel()"
    21. [height]="menuHeight">
    22. </Menu>
    23. <div *ngIf="show && !initData" style="width: 100% ;height: 200px; display: flex; justify-content: center; align-items: center">
    24. <ActivityIndicator [size]="'large'"></ActivityIndicator>
    25. </div>
    26. <div *ngIf="show" class="menu-mask3" (click)="onMaskClick()"></div>
    27. </div>
    28. `,
    29. styles: [
    30. `
    31. .multi-foo-menu {
    32. position: absolute;
    33. z-index: 80 !important;
    34. width: 100%;
    35. }
    36. .multi-menu-active .multi-top-nav-bar {
    37. z-index: 80;
    38. }
    39. .multi-top-nav-bar {
    40. position: relative;
    41. background-color: #008ae6;
    42. color: #fff;
    43. }
    44. .menu-mask3 {
    45. content: ' ';
    46. position: absolute;
    47. top: 0;
    48. width: 100%;
    49. height: 100%;
    50. background-color: #000;
    51. opacity: 0.4;
    52. z-index: 79;
    53. }
    54. `
    55. ],
    56. encapsulation: ViewEncapsulation.None
    57. })
    58. export class DemoMenuMultiSelectComponent {
    59. initData: Array<any>;
    60. show: boolean = false;
    61. menuHeight: number = document.documentElement.clientHeight * 0.6;
    62. dataMenu: Array<any> = [
    63. {
    64. value: '1',
    65. label: 'Food',
    66. children: [
    67. {
    68. label: 'All Foods',
    69. value: '1',
    70. disabled: false
    71. },
    72. {
    73. label: 'Chinese Food',
    74. value: '2'
    75. },
    76. {
    77. label: 'Hot Pot',
    78. value: '3'
    79. },
    80. {
    81. label: 'Buffet',
    82. value: '4'
    83. },
    84. {
    85. label: 'Fast Food',
    86. value: '5'
    87. },
    88. {
    89. label: 'Snack',
    90. value: '6'
    91. },
    92. {
    93. label: 'Bread',
    94. value: '7'
    95. },
    96. {
    97. label: 'Fruit',
    98. value: '8'
    99. },
    100. {
    101. label: 'Noodle',
    102. value: '9'
    103. },
    104. {
    105. label: 'Leisure Food',
    106. value: '10'
    107. }
    108. ]
    109. },
    110. {
    111. value: '2',
    112. label: 'Supermarket',
    113. children: [
    114. {
    115. label: 'All Supermarkets',
    116. value: '1'
    117. },
    118. {
    119. label: 'Supermarket',
    120. value: '2',
    121. disabled: true
    122. },
    123. {
    124. label: 'C-Store',
    125. value: '3'
    126. },
    127. {
    128. label: 'Personal Care',
    129. value: '4'
    130. }
    131. ]
    132. },
    133. {
    134. value: '3',
    135. label: 'Extra',
    136. isLeaf: true,
    137. children: [
    138. {
    139. label: 'you can not see',
    140. value: '1'
    141. }
    142. ]
    143. }
    144. ];
    145. onChange(value) {
    146. console.log(value);
    147. }
    148. handleClick(e) {
    149. e.preventDefault();
    150. this.show = !this.show;
    151. if (!this.initData) {
    152. setTimeout(() => {
    153. this.initData = this.dataMenu;
    154. }, 500);
    155. }
    156. }
    157. onMaskClick() {
    158. this.show = false;
    159. }
    160. onOk(value) {
    161. console.log(value);
    162. this.onCancel();
    163. }
    164. onCancel() {
    165. this.show = false;
    166. }
    167. }

    单级菜单多选

    1. import { Component, ViewEncapsulation } from '@angular/core';
    2. @Component({
    3. selector: 'demo-menu-singleMulti',
    4. template: `
    5. <div [ngClass]="[show ? 'single-multi-menu-active' : '']">
    6. <div>
    7. <Navbar [leftContent]="'Menu'"
    8. (onLeftClick)="handleClick($event)"
    9. class="single-multi-top-nav-bar">
    10. Here is title
    11. </Navbar>
    12. </div>
    13. <Menu *ngIf="show && initData"
    14. class="single-multi-foo-menu"
    15. [data]="initData"
    16. [value]="['1']"
    17. [level]="1"
    18. [multiSelect]="true"
    19. (onChange)="onChange($event)"
    20. (onOk)="onOk($event)"
    21. (onCancel)="onCancel()"
    22. [height]="menuHeight">
    23. </Menu>
    24. <div *ngIf="show && !initData" style="width: 100% ;height: 200px; display: flex; justify-content: center; align-items: center">
    25. <ActivityIndicator [size]="'large'"></ActivityIndicator>
    26. </div>
    27. <div *ngIf="show" class="menu-mask4" (click)="onMaskClick()"></div>
    28. </div>
    29. `,
    30. styles: [
    31. `
    32. .single-multi-foo-menu {
    33. position: absolute;
    34. z-index: 70 !important;
    35. width: 100%;
    36. }
    37. .single-multi-menu-active .single-multi-top-nav-bar {
    38. z-index: 80;
    39. }
    40. .single-multi-top-nav-bar {
    41. position: relative;
    42. background-color: #008ae6;
    43. color: #fff;
    44. }
    45. .menu-mask4 {
    46. content: ' ';
    47. position: absolute;
    48. top: 0;
    49. width: 100%;
    50. height: 100%;
    51. background-color: #000;
    52. opacity: 0.4;
    53. z-index: 69;
    54. }
    55. `
    56. ],
    57. encapsulation: ViewEncapsulation.None
    58. })
    59. export class DemoMenuSingleMultiComponent {
    60. initData: Array<any>;
    61. show: boolean = false;
    62. menuHeight: number = document.documentElement.clientHeight * 0.6;
    63. data: Array<any> = [
    64. {
    65. value: '1',
    66. label: 'Food'
    67. },
    68. {
    69. value: '2',
    70. label: 'Supermarket'
    71. },
    72. {
    73. value: '3',
    74. label: 'Extra',
    75. isLeaf: true
    76. }
    77. ];
    78. onChange(value) {
    79. console.log(value);
    80. }
    81. handleClick(e) {
    82. e.preventDefault();
    83. this.show = !this.show;
    84. if (!this.initData) {
    85. setTimeout(() => {
    86. this.initData = this.data;
    87. }, 500);
    88. }
    89. }
    90. onMaskClick() {
    91. this.show = false;
    92. }
    93. onOk(value) {
    94. console.log(value);
    95. this.onCancel();
    96. }
    97. onCancel() {
    98. console.log('onCancel');
    99. this.show = false;
    100. }
    101. }

    Menu 菜单 - 图1

    API

    属性说明类型默认值
    data数据(isLeaf 设置后 children 无效)Array<{label: string, value, disabled?, children<data>?, isLeaf?}>[]
    level菜单级数,可选1/2number2
    value初始值,一级和二级筛选数据的value组成的数组。在多选状态下,如果为二级菜单,则数组的第一个元素为一级菜单的选项,数组的第二个元素是一个数组,里面包含了二级菜单的多选项;如果为一级菜单,则数组所有元素都是多选项Array
    onChange选择后的回调函数(item: Object): void
    onOk多选状态下确认按钮回调(value: Object): void
    onCancel多选状态下取消按钮回调(): void
    height筛选组件的高度numberdocument.documentElement.clientHeight / 2
    multiSelect是否支持菜单多选booleanfalse