亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

react antd-mobile ActionSheet+tag實現(xiàn)多選方式

 更新時間:2023年10月23日 11:15:32   作者:YING-FINE  
這篇文章主要介紹了react antd-mobile ActionSheet+tag實現(xiàn)多選方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

實現(xiàn)效果如下

在手機(jī)下方彈出彈窗

選擇月份點確定后

再次點擊申請月份,之前已選的月份會自動選上

全部功能描述

1、點擊輸入框,自動彈出選擇彈窗(使用actionsheet,這部分不過多闡釋)

2、彈窗可多選的內(nèi)容由后臺接口傳入(或自己寫數(shù)據(jù),看需求)

3、灰色部分為后臺返回的不可選擇的標(biāo)簽,不允許用戶點擊選擇(disabled)

4、選擇一個或多個標(biāo)簽后,點擊確定,保存選擇的標(biāo)簽,并在輸入框中顯示選擇的內(nèi)容。倘若沒有點擊確定,直接點取消或彈框外的區(qū)域關(guān)閉彈窗,則不會保存所選標(biāo)簽

4、再次點擊輸入框,彈窗會自動勾選上之前選過的彈窗。之后操作可如上循環(huán)。

功能實現(xiàn)

一、從后臺獲取所有月份信息

這里就是普通的通過redux的網(wǎng)絡(luò)請求獲取數(shù)據(jù),按實際情況獲取數(shù)據(jù)

  getMouth = () => {
    const {dispatch} = this.props;
    dispatch({
      type: `${NAMESPACE}/getMouth`,
    });
  };

不允許點擊的月份

const disabledMouth = [2,5,8];

按理說,不允許點擊的月份也應(yīng)該通過后臺獲取,此處因為還沒拿到后臺接口,暫時用全局變量充當(dāng)不允許點擊的月份數(shù)組

二、添加組件的state數(shù)據(jù)

this.state = {
      checkMouth: [],//保存已選擇的月份
      allMouth: [],//保存月份標(biāo)簽的屬性數(shù)據(jù)
      temCheckMouth: [],//臨時保存已選擇的魚粉
      temAllMouth: [],//臨時保存月份標(biāo)簽的屬性數(shù)據(jù)
      sign: false//判斷用戶是否點擊確定
}

三、定義含有標(biāo)簽屬性的數(shù)組allMouth

getAllMouth = () => {
	//mouth即為第一步通過后臺拿到的model里state的月份值
    const mouth = this.props.mouth.data || '';
    const newMonth = [];
    if (mouth && mouth.length > 0) {
      mouth.map(item => {
        newMonth.push(
          {
            value: item.code,//可理解為每個月份的id
            label: item.detail,//月份標(biāo)簽需展示的內(nèi)容,如一月、二月等的字樣
            selected: false,//月份標(biāo)簽是否被選擇
            disabled: false//該月份是否不可點擊
          }
        )
      });
    }
    // 修改無法選擇的月份信息,把無法選擇的月份disabled置灰掉,不允許用戶點擊選擇
    disabledMouth.map(item => {
      newMonth[item].disabled = true;
    });
    // console.log(newMonth);

	// 把每個月份的屬性數(shù)據(jù)數(shù)組存入state
    this.setState({
      allMouth: newMonth,
      temAllMouth: newMonth
    })
  };

注:

一般后臺傳的數(shù)據(jù)只會有code和detail或其他內(nèi)容,不會有selected和disabled,所以此處我們要在數(shù)組手動添加,給每個月份自己獨有的selected值和disabled值。

在最初默認(rèn)都是未選中和允許點擊狀態(tài)。

四、保存月份屬性數(shù)組allMouth

  componentDidMount() {
    let timer;
    new Promise(resolve => {
      this.getMouth();
      timer = setInterval(() => {
        if (this.props.mouth.data) {
          resolve();
        }
      }, 100);
    }).then(() => {
      this.getAllMouth();
      clearInterval(timer);
    });
  }

這部分代碼其實我考慮了很久,因為這里有一個前提條件

必須通過getMouth()后臺請求到數(shù)據(jù)之后,getAllMouth()才能訪問數(shù)據(jù),初始化月份數(shù)組數(shù)據(jù)并放到state

但是在這一步我報錯了很久,因為倘若普通寫法(如下)

this.getMouth();×
this.getAllMouth();×

這一步雖然顯示網(wǎng)絡(luò)請求成功了,但是props.mouth并沒有拿到數(shù)據(jù)!

這一步該如何寫思考了很久,直接簡單實用promise也不行

  componentDidMount() {    ×
    new Promise(resolve => {    ×
      this.getMouth();    ×
          resolve();    ×
    }).then(() => {    ×
      this.getAllMouth();    ×
    });    ×
  }    ×

此處getMouth()方法的確是執(zhí)行完了,只是還沒拿到數(shù)據(jù),所以這樣子寫是不行的

而且componentDidMount正常來說只會執(zhí)行一次,所以在componentDidMount執(zhí)行完,而model的state還沒拿到數(shù)據(jù)的時候,盡管過了一段時間拿到數(shù)據(jù)了this.getAllMouth(); 也不會再次執(zhí)行了,所以初始化無法進(jìn)行。

思前想后,能解決這一步的只能多次執(zhí)行,確保拿到數(shù)據(jù)了,再進(jìn)行this.getAllMouth();初始化數(shù)據(jù)。便有了上方代碼的操作。

當(dāng)然,開了定時器記得用完就關(guān)!這一步操作可能性能上不太友好,如果大家有什么更好的方法,請多多指教呀~

五、遍歷顯示月份

上面步驟成功后,可以看到我們初始化的月份數(shù)組allMouth是這樣的,接下來就可以讓他們展示出來了

(注:0號全選是后臺一同傳過來的,大家可忽略)

input框:

<div onClick={this.handleMouth}>
	<InputItem placeholder="請選擇申請月份" readonly="readonly" clear >
		申請月份
	</InputItem>
</div>

點擊后彈出彈窗

主要是使用ActionSheet彈出彈窗顯示內(nèi)容,不多闡述。詳情可見antd-mobile文檔

  handleMouth = () => {
    const {allMouth} = this.state;
    //這一步是為了刪去數(shù)組第一條全選數(shù)據(jù),全選不需要顯示。可忽略
    const newMouthData = allMouth && allMouth.slice(1);

    const modalData = (
      <div className={styles.modalStyle}>
        <div className={styles['tag-body']}>
          <div style={{textAlign: 'left'}}>可選擇月份(可多選)</div>
          <div className={styles['tag-box']}>
            {
              newMouthData && newMouthData.map((item) => {
                return (
                  <Tag
                    data-seed="logId"
                    onChange={(selected) => this.handleOnTagChange(selected, item.value)} // 用戶點擊不同月份時觸發(fā)的方法(詳情見下方標(biāo)題六)
                    selected={item.selected}// 控制不同月份的選中狀態(tài)
                    disabled={item.disabled}// 控制不同月份是否可點擊
                  >
                    {item.label}
                  </Tag>
                )
              })
            }
          </div>
        </div>
      </div>
    )
    const button1 = (
      <div className={styles.buttonStyle}>
        <span>取消</span>
        <span onClick={this.handleConfirm}>確定</span>//詳情請見標(biāo)題七的內(nèi)容
      </div>
    )
    const BUTTONS = [modalData];
    ActionSheet.showActionSheetWithOptions({
        options: [button1],
        message: BUTTONS,
      },
      // 關(guān)閉頁面執(zhí)行的方法
      (buttonIndex) => {
		this.closePage();//詳情請見標(biāo)題八的內(nèi)容
      });
  };

六、選擇不同月份觸發(fā)事件

handleOnTagChange = (selected, value) => {
	/**
	*  用戶在彈窗選擇月份時,雖然當(dāng)前處于選中狀態(tài)。
	*  但是倘若用戶選擇完畢時不點擊確定,而且直接關(guān)閉頁面
	*  則之前選中的月份都不應(yīng)該保存!所以此處用臨時數(shù)組進(jìn)行保存
	*  只有用戶點擊確定,才把選擇的所有內(nèi)容保存到正式的數(shù)組中
	*/
    const {temAllMouth, temCheckMouth} = this.state;

    // 修改月份對應(yīng)的selected屬性
    const newAllMouth = JSON.parse(JSON.stringify(temAllMouth));
    newAllMouth[value].selected = selected;
    // console.log(newAllMouth);

    // 記錄選中的月份
    const newCheckMouth = JSON.parse(JSON.stringify(temCheckMouth));
    if (selected) {//如果選中,把選中的月份添加進(jìn)數(shù)組
      newCheckMouth.push(parseInt(value));
    } else {//如果是取消選中,需要把之前的選中從數(shù)組中刪除
      const deleteMouth = newCheckMouth.findIndex(item => item == value);
      newCheckMouth.splice(deleteMouth, 1);
    }
    // console.log(newCheckMouth);

    this.setState({
      temCheckMouth: newCheckMouth,
      temAllMouth: newAllMouth
    });
  };

關(guān)于const newAllMouth = JSON.parse(JSON.stringify(temAllMouth))的解釋:

這一步其實我繞了很多彎路,最后一步步排除錯誤才發(fā)現(xiàn)我犯了個超級低級的錯誤!

因為這個方法中,我們很明顯需要修改數(shù)組,但是我們不能直接修改state的數(shù)據(jù)

所以必須在方法中深拷貝state的數(shù)組,對新數(shù)組進(jìn)行修改,最后再通過setstate把新數(shù)組賦值給state的數(shù)組。

而在寫代碼最初,我是直接

const {temAllMouth, temCheckMouth} = this.state;
const newAllMouth = temAllMouth;×××××錯誤范例?。?!

很明顯這樣寫是錯誤的!直接賦值是把temAllMouth的地址賦值給了newAllMouth ,兩者其實沒有區(qū)別,修改newAllMouth 也會修改到state的數(shù)據(jù)temAllMouth,故出現(xiàn)問題。

所以最后直接把temAllMouth通過JSON深拷貝一份,保證newAllMouth與temAllMouth不相同,互不干擾。

七、點擊確定觸發(fā)實現(xiàn)

handleConfirm = () => {
    const {temCheckMouth, temAllMouth} = this.state;

    /**
    * 對選中月份進(jìn)行排序
    * 因為關(guān)閉彈窗后需要在input框中顯示用戶選擇的月份
    * 而用戶選擇的順序是不定,所以temCheckMouth保存的選中月份也是亂的
    * 故此處為了美觀,對選中月份進(jìn)行了排序
    * 使用的是最簡單的冒泡排序,可以忽略
    */
    const newCheckMouth = JSON.parse(JSON.stringify(temCheckMouth));
    if (newCheckMouth && newCheckMouth.length > 1){
      newCheckMouth.map((item,index) => {
        for (let j = 0; j<newCheckMouth.length-index;j+=1){
          if (newCheckMouth[j] > newCheckMouth[j + 1]){
            const temp = newCheckMouth[j];
            newCheckMouth[j] = newCheckMouth[j + 1];
            newCheckMouth[j + 1] = temp;
          }
        }
      });
    }
    console.log('選中的月份--' + newCheckMouth);

	// 此時用戶點擊確定按鈕,需要把之前保存的臨時數(shù)據(jù)賦值給正式的數(shù)組
    this.setState({
      allMouth: temAllMouth,
      checkMouth: newCheckMouth,
      temCheckMouth: newCheckMouth,
      sign: true //確定頁面
    });

	// 把選中的月份展示在input框,只有用戶有選擇月份的情況才需要展示
    if (temCheckMouth){
      this.props.form.setFieldsValue({ sqzzjtyf: newCheckMouth.toString() });
    }
  }

八、關(guān)閉彈窗觸發(fā)事件

注:這里關(guān)閉彈窗并不是點擊取消或者點擊彈窗外的手機(jī)部分關(guān)閉彈窗時才會觸發(fā)?。?/p>

點擊確定之后關(guān)閉彈窗同樣會觸發(fā)?。。。]注意這部分就會出現(xiàn)錯誤!

	closePage = () => {
        setTimeout(()=>{
          const {checkMouth, allMouth, sure} = this.state;
          // sure=false代表用戶沒有點擊確定,則需要把之前保存的臨時數(shù)據(jù)重置,保證用戶下次打開彈窗時數(shù)據(jù)的正確性
          if(!sure){
            this.setState({
              temCheckMouth: checkMouth,
              temAllMouth: allMouth
            });
          }else{ // 把點擊確定時修改的sure=true修改回false,保證下次再次打開彈窗的正確性
            this.setState({
              sure: false
            });
          }
        },50)
	}

此處使用settimeout的原因:

上面也說了,這里調(diào)用的方法是只要關(guān)閉了彈窗就會執(zhí)行,而該方法的執(zhí)行順序與用戶點擊確定的執(zhí)行順序應(yīng)該是不相上下的(此處未做深入研究,不確定兩者的執(zhí)行順序)

而這里我們有一個必須前提,關(guān)閉彈窗的這個方法必須在點擊確定的方法后面執(zhí)行,原因如下:

在點擊確定方法后,我們會設(shè)置sure=true,并且把checkMouth和allMouth設(shè)置為新的值

而倘若關(guān)閉彈窗方法沒有在確定方法后執(zhí)行,則關(guān)閉彈窗方法執(zhí)行的時候,sure值仍為false!并且checkMouth和allMouth也扔為舊值

這樣,該方法就會執(zhí)行

      temCheckMouth: checkMouth(舊值),
      temAllMouth: allMouth(舊值)

如此,用戶之前點擊確定應(yīng)該要保存的數(shù)據(jù)就沒有保存成功了!錯誤就出現(xiàn)了!

故此處使用settimeout保證該方法執(zhí)行的延后!

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • react native圖片解析流程詳解

    react native圖片解析流程詳解

    這篇文章主要為大家介紹了react native圖片解析流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • react native基于FlatList下拉刷新上拉加載實現(xiàn)代碼示例

    react native基于FlatList下拉刷新上拉加載實現(xiàn)代碼示例

    這篇文章主要介紹了react native基于FlatList下拉刷新上拉加載實現(xiàn)代碼示例
    2018-09-09
  • React Native第三方平臺分享的實例(Android,IOS雙平臺)

    React Native第三方平臺分享的實例(Android,IOS雙平臺)

    本篇文章主要介紹了React Native第三方平臺分享的實例(Android,IOS雙平臺),具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • React高級概念之Context用法詳解

    React高級概念之Context用法詳解

    在React應(yīng)用中,為了讓數(shù)據(jù)在組件間共享,常見的方式是讓它們以props的形式自頂向下傳遞,如果數(shù)據(jù)要在組件樹不同層級共享,那么這些數(shù)據(jù)必須逐層傳遞直到目的地,Context如同管道,它將數(shù)據(jù)從入口直接傳遞到出口,使用Context能避免“prop-drilling”
    2023-06-06
  • react如何實現(xiàn)表格多條件搜索

    react如何實現(xiàn)表格多條件搜索

    這篇文章主要介紹了react如何實現(xiàn)表格多條件搜索問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React高級指引之Refs and the DOM使用時機(jī)詳解

    React高級指引之Refs and the DOM使用時機(jī)詳解

    在典型的React數(shù)據(jù)流中,props是父組件與子組件交互的唯一方式。要修改一個子組件,你需要使用新的props來重新渲染它。但是,在某些情況下,你需要在典型數(shù)據(jù)流之外強(qiáng)制修改子組件
    2023-02-02
  • React配置子路由的實現(xiàn)

    React配置子路由的實現(xiàn)

    本文主要介紹了React配置子路由的實現(xiàn),我們來通過一個簡單的例子解釋一下如何配置子路由,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • React利用路由實現(xiàn)登錄界面的跳轉(zhuǎn)

    React利用路由實現(xiàn)登錄界面的跳轉(zhuǎn)

    這篇文章主要介紹了React利用路由實現(xiàn)登錄界面的跳轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局

    react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局

    這篇文章主要為大家詳細(xì)介紹了react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局,一個路由小案例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • React中事件綁定this指向三種方法的實現(xiàn)

    React中事件綁定this指向三種方法的實現(xiàn)

    這篇文章主要介紹了React中事件綁定this指向三種方法的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評論