index.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { VantComponent } from '../common/component';
  2. const ITEM_HEIGHT = 44;
  3. VantComponent({
  4. classes: [
  5. 'main-item-class',
  6. 'content-item-class',
  7. 'main-active-class',
  8. 'content-active-class',
  9. 'main-disabled-class',
  10. 'content-disabled-class'
  11. ],
  12. props: {
  13. items: Array,
  14. activeId: null,
  15. mainActiveIndex: {
  16. type: Number,
  17. value: 0
  18. },
  19. maxHeight: {
  20. type: Number,
  21. value: 300
  22. },
  23. max: {
  24. type: Number,
  25. value: Infinity
  26. }
  27. },
  28. data: {
  29. subItems: [],
  30. mainHeight: 0,
  31. itemHeight: 0
  32. },
  33. watch: {
  34. items() {
  35. this.updateSubItems().then(() => {
  36. this.updateMainHeight();
  37. });
  38. },
  39. maxHeight() {
  40. this.updateItemHeight(this.data.subItems);
  41. this.updateMainHeight();
  42. },
  43. mainActiveIndex: 'updateSubItems'
  44. },
  45. methods: {
  46. // 当一个子项被选择时
  47. onSelectItem(event) {
  48. const { item } = event.currentTarget.dataset;
  49. const isArray = Array.isArray(this.data.activeId);
  50. // 判断有没有超出右侧选择的最大数
  51. const isOverMax = isArray && (this.data.activeId.length >= this.data.max);
  52. // 判断该项有没有被选中, 如果有被选中,则忽视是否超出的条件
  53. const isSelected = isArray ? this.data.activeId.indexOf(item.id) > -1 : this.data.activeId === item.id;
  54. if (!item.disabled && (!isOverMax || isSelected)) {
  55. this.$emit('click-item', item);
  56. }
  57. },
  58. // 当一个导航被点击时
  59. onClickNav(event) {
  60. const { index } = event.currentTarget.dataset;
  61. const item = this.data.items[index];
  62. if (!item.disabled) {
  63. this.$emit('click-nav', { index });
  64. }
  65. },
  66. // 更新子项列表
  67. updateSubItems() {
  68. const { items, mainActiveIndex } = this.data;
  69. const { children = [] } = items[mainActiveIndex] || {};
  70. this.updateItemHeight(children);
  71. return this.set({ subItems: children });
  72. },
  73. // 更新组件整体高度,根据最大高度和当前组件需要展示的高度来决定
  74. updateMainHeight() {
  75. const { items = [], subItems = [] } = this.data;
  76. const maxHeight = Math.max(items.length * ITEM_HEIGHT, subItems.length * ITEM_HEIGHT);
  77. this.setData({ mainHeight: Math.min(maxHeight, this.data.maxHeight) });
  78. },
  79. // 更新子项列表高度,根据可展示的最大高度和当前子项列表的高度决定
  80. updateItemHeight(subItems) {
  81. const itemHeight = Math.min(subItems.length * ITEM_HEIGHT, this.data.maxHeight);
  82. return this.setData({ itemHeight });
  83. }
  84. }
  85. });