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