Ant design mobile Actionsheet 組件的思考和改進

使用螞蟻金服的 ant-design UI 組件庫的移動端組件時,最近遇到一個問題。

官方的模板是這樣的

  showActionSheet = () => {
    const BUTTONS = ['Operation1', 'Operation2', 'Operation2', 'Delete', 'Cancel'];
    ActionSheet.showActionSheetWithOptions({
      options: BUTTONS,
      cancelButtonIndex: BUTTONS.length - 1,
      destructiveButtonIndex: BUTTONS.length - 2,
      message: 'I am description, description, description',
      maskClosable: true,
    },
    (buttonIndex) => {
      this.setState({ clicked: BUTTONS[buttonIndex] });
    });
  }

如果一個菜單是動態的(不同情況,會創建不同的菜單,菜單的個數和內容不同),那麼回調函數中,返回的 buttonIndex 所執行的函數就很難處理。下面想了兩個結局按方案

思路一:使用享元模式,優化多重的IF循環

這樣需要引入新的變量

實際的代碼如下

showActionSheet = () => {
    let buttons = [{
      dom : <div className="my-am-action"><i className={`${font}rename`}></i>{t('Rename')}</div>,
      value: 'rename',
    }];
  	// In different situations, push special object(contain dom and value) into buttonArray
    if (!isNameColumn) {
      buttons.push({
        dom: <div className="my-am-action"><i className={`${font}test`}></i>{t('test')}</div>,
        value: 'test',
      });
    }
  	// This is real buttons array (ActionSheet use it)
    let optionButtons = [];
    for (let i = 0; i < buttons.length; i++) {
      optionButtons.push(buttons[i].dom);
    }
    ActionSheet.showActionSheetWithOptions({ options: optionButtons, maskClosable: true }, (buttonIndex) => {
      this.setState({ isMenuShow: false });
      const value = optionButtons[buttonIndex];
      this.onActionSheetClick(value);
    });
  }

  onActionSheetClick = (value) => {
    switch(value) {
      case 'rename':
        this.onRename();
        break;
      case 'test':
        this.onHideColumn();
        break;
    }
  }

這樣的優點是:每一個情況對應一個字符串,把index轉換成字符串,然後根據字符串進行回調函數處理。

不足:需要新增加一個數組,存儲字符串變量。

思路二:直接對每一個菜單元素,監聽onClick事件

這樣的缺點是,每一個都需要設置回調函數,和原生的 ActionSheet 的回調函數無關,特殊情況下,無法控制點擊事件(按鈕不能點擊)

if (sortColumnOptions.includes(columnType)) {
      buttons.push(
        <div className="my-am-action" onClick={(e) => this.modifySort(SORT_TYPE.UP, e)}><i className={`${font}ascending-order`}></i>{t('Sort_Ascending')}</div>,
        <div className="my-am-action" onClick={(e) => this.modifySort(SORT_TYPE.DOWN, e)}><i className={`${font}descending-order`}></i>{t('Sort_Descending')}</div>
      );
    }

綜合這兩種方法,我個人更認同第一種做法

當然,還可以基於第三方 ant design mobile 組件,自己再寫一個適合自己項目的組件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章