精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用Antd表格組件實現(xiàn)日程表

開發(fā) 前端
20多天前,遇到一個日程表的業(yè)務(wù)需求,可以動態(tài)增加列、對單元格進行合并,結(jié)合公司的jsp項目的已有功能完成單元格的增、刪、改操作。

[[353267]]

本文轉(zhuǎn)載自微信公眾號「神奇的程序員K」,作者神奇的程序員K 。轉(zhuǎn)載本文請聯(lián)系神奇的程序員K公眾號。

 前言

20多天前,遇到一個日程表的業(yè)務(wù)需求,可以動態(tài)增加列、對單元格進行合并,結(jié)合公司的jsp項目的已有功能完成單元格的增、刪、改操作。進行需求分析整理后,經(jīng)過了一番查找,發(fā)現(xiàn)React版本的antd的表格組件功能很強大,可定制程度很高,可以助我完成這個業(yè)務(wù)需求的開發(fā)。

由于要和jsp進行交互,所以在實現(xiàn)過程中,遇到了一些難題踩了挺多坑,本文就跟大家分享下我從0到1實現(xiàn)這個需求的過程與思路,歡迎各位感興趣的開發(fā)者閱讀本文。

環(huán)境搭建

因為公司的項目是基于jsp的,antd本想用Vue版本的,無奈它與jsp的一些語法沖突了跑不起來,于是就嘗試了react版本的antd,它跑起來了沒有發(fā)現(xiàn)任何兼容性問題,一切正常。給React點個贊??。

由于要與項目中已有的功能進行交互,沒法用腳手架,我只能以cdn的方式引入react,如下所示,按順序引入react、axios、lodah以及antd所需要的文件。

  1. <script crossOrigin type="text/javascript" src="lib/react.production.min.js"></script> 
  2.    <script crossOrigin type="text/javascript" src="lib/react-dom.production.min.js"></script> 
  3.    <script src="lib/babel.min.js"></script> 
  4.    <script type="text/javascript" src="lib/moment.min.js"></script> 
  5.    <script src="lib/lodash.min.js"></script> 
  6.    <script type="text/javascript" src="lib/antd.min.js"></script> 
  7.    <script type="text/javascript" src="lib/axios.min.js"></script> 
  8.    <link rel="stylesheet" href="lib/antd.min.css"

 

 

 

 

 

 

 

 

上述用到的資源文件地址: react-antd-schedule/lib

我們需要把react相關(guān)代碼寫在text/babel標簽中,如下所示,我們打印antd和react看看是否有值。

  1. <script type="text/babel"
  2.     console.log("react"); 
  3.     console.log(React); 
  4.     console.log("antd"
  5.     console.log(antd); 
  6. </script> 

 

打開瀏覽器控制臺,出現(xiàn)下述信息,代表我們的環(huán)境已經(jīng)搭建成功。

image-20201119155715157

接下來,我們寫個HelloWord來測試下效果。

  1. <div id="root" style="width: 94%;overflow: hidden"></div> 
  2. <script type="text/babel"
  3.     // 自定義hook 
  4.     const App = () => { 
  5.         const onChange = (date, dateString) => { 
  6.             console.log(date, dateString); 
  7.         } 
  8.         return ( 
  9.             <div> 
  10.                 React+antd引入成功 
  11.                 <br /> 
  12.                 <antd.DatePicker onChange={onChange} /> 
  13.             </div> 
  14.         ); 
  15.     }; 
  16.     ReactDOM.render(<App />, document.getElementById("root")); 
  17. </script> 

 

 

 

 

執(zhí)行上述代碼,打開瀏覽器如果看到下述效果,就證明我們的環(huán)境已經(jīng)搭好了。

image-20201119161505912

需要注意的是,CDN引入React和antd,他們是在全局暴露了一個對象,在使用它內(nèi)部的方法時就需要React.xx、antd.xx來訪問了。

需求分析

當(dāng)我收到需求簡述后,我對其進行了整理:

  • 表格列要展示的內(nèi)容:日期、日程內(nèi)容(接口動態(tài)返回),日程內(nèi)容列用戶可以自己手動增加。
  • 表格行展示的內(nèi)容為每一天的數(shù)據(jù),每一天的數(shù)據(jù)分為:上午、下午、晚上三個時間段。
  • 日程內(nèi)容分為天日程和某個時間段的日程兩種狀態(tài),如果為天日程則需要進行單元格合并。
  • 日程內(nèi)容列的每個單元格有5種狀態(tài),需要通過某種方式來區(qū)分,讓用戶一眼就能看出當(dāng)前日程處于什么狀態(tài)。
  • 日程內(nèi)容單元格的內(nèi)容如果為空時,需要將單元格進行合并,顯示一個增加圖標,點擊增加圖標后,打開系統(tǒng)的彈窗進行增加操作,操作完成后,渲染內(nèi)容至剛才點擊的單元格。
  • 如果內(nèi)容單元格有內(nèi)容時,根據(jù)不同的狀態(tài),打開不同的彈窗進行改、刪操作,操作完后,更新結(jié)果至對應(yīng)的單元格。

需求確定后,老板給我分了一個后端,跟后端溝通后開發(fā)周期估了1周,我頁面估了2天的時間,剩下的3天與后端進行數(shù)據(jù)對接。

2天后,我把頁面弄完了,表格需要的數(shù)據(jù)格式也定義好了,把數(shù)據(jù)格式發(fā)給后端后,他說好,沒問題。

因為沒有UI給設(shè)計圖,所以第一版,我就憑著自己的直覺來弄了,搞出來的東西蠻丑的,下圖就是我根據(jù)需求實現(xiàn)的頁面。

image-20201119172808318

然而,事情沒有預(yù)想中那么順利,我頁面做好后,到開發(fā)周期的最后一天下午,后端把接口給我了,但返回的數(shù)據(jù)不是我預(yù)想的格式,我又進行了二次處理,頁面渲染出來后,快到下班時間了,到了預(yù)估的開發(fā)時間沒有完成需求,倒也能理解,畢竟后端那邊要處理的數(shù)據(jù)比較復(fù)雜。

本來預(yù)估了一周的開發(fā)時間,后面需求的不斷增加、變更、UI設(shè)計效果圖,我的頁面代碼也從一開始的100多行累加到現(xiàn)在的1000多行,這一套折騰下來,直到需求開發(fā)完成交給測試,花了20多天的時間。

需求實現(xiàn)

接下來,就跟大家分享下在實現(xiàn)這個需求時,遇到的難點、踩到的一些坑以及我的解決方案。

最后實現(xiàn)的效果如下所示,實現(xiàn)代碼請移步:react-antd-schedule/index.html

image-20201119175256753

動態(tài)增加列

這個日程表用戶可以通過點增加圖標來增加一列日程,此時我們就需要往表格頭部增加一列數(shù)據(jù),一開始我覺得只要往antd的columns和dataSource中添加一條數(shù)據(jù)就行了,如下所示:

  1. const App = () => { 
  2.         const [columns, setColumns] = React.useState([]); 
  3.         const [optRecords, setOptRecords] = React.useState([]); 
  4.            //增加按鈕函數(shù) 
  5.         const btnClick = (e) => { 
  6.             index++; 
  7.             let columnsObj = { 
  8.                 dataIndex: 'rcnr' + (index), 
  9.                 title: '日程內(nèi)容' + index
  10.                 align: 'center'
  11.                 onCell: tdSet, 
  12.                 render: rctd_render, 
  13.             } 
  14.             // 表格列新增一列 
  15.             columns.push(columnsObj) 
  16.             setColumns(columns); 
  17.             // 處理表格數(shù)據(jù) 
  18.             for (let i = 0; i < optRecords.length; i++) { 
  19.                 let key = "rcnr"+index
  20.                 // 表格數(shù)據(jù)新增一條 
  21.                 optRecords[i][key] = {text:"", code:"0"
  22.             } 
  23.             setOptRecords(optRecords); 
  24.         } 
  25.  } 

當(dāng)我在瀏覽器執(zhí)行看效果時,發(fā)現(xiàn)沒有生效,于是我下意識的打開了瀏覽器控制臺看看是不是報錯了,啪的一下,很快啊~新增加的那一列被渲染上去了,我大E了啊,antd不講武德啊。

于是,我多試了幾次,發(fā)現(xiàn)還是不渲染,打開控制臺后就奇跡般的渲染上去了,有點摸不著頭腦,就求助了下網(wǎng)友,我才恍然大悟,原來是antd沒有監(jiān)聽到引用地址的改變,得到了下述解決方案,用一個函數(shù)去處理它,讓antd監(jiān)聽到引用地址改變,它才會將數(shù)據(jù)進行渲染。

  1. const App = () => { 
  2.        const [optRecords, setOptRecords] = React.useState([]); 
  3.        const [columns, setColumns] = React.useState([]); 
  4.           //增加按鈕函數(shù) 
  5.        const btnClick = (e) => { 
  6.            if (tableLoadingStatus) { 
  7.                alert("表格數(shù)據(jù)尚未加載完成"); 
  8.                return false
  9.            } 
  10.            columnsIndex++; 
  11.            let columnsObj = { 
  12.                dataIndex: "rcnr" + (columnsIndex), 
  13.                title: "日程內(nèi)容" + columnsIndex, 
  14.                align: "left"
  15.                className: "rcnrfontSet"
  16.                width: 189.5, 
  17.                onCell: tdSet, 
  18.                render: rctd_render 
  19.            }; 
  20.            // 表格列新增一列 
  21.            setColumns((arr => [...arr, columnsObj])); 
  22.            // 處理表格數(shù)據(jù) 
  23.            setOptRecords((arr) => arr.map((item) => { 
  24.                return { ...item, ["rcnr" + columnsIndex]: { wz: columnsIndex - 1 } }; 
  25.            })); 
  26.             
  27.        }; 

表格列補齊

在后端返回的數(shù)據(jù)中,如果有不存在的日程,直接連字段都沒返回,這就造成了antd在渲染的時候列與表格數(shù)據(jù)不對應(yīng)而引發(fā)的武發(fā)渲染的問題,于是我只能把所有數(shù)據(jù)遍歷一遍,求出最大列長度,然后將列少的數(shù)據(jù)進行補全,由于添加數(shù)據(jù)時接口需要傳當(dāng)前點擊的是哪一列,剛才補全的數(shù)據(jù)中是不包含wz字段的,因此我們需要再遍歷一次數(shù)據(jù),把wz字段加上去,代碼如下:

  1. // 表格數(shù)據(jù)渲染函數(shù) 
  2.         const tableDataRendering = function(res) { 
  3.           // 獲取最大子節(jié)點的key數(shù)量 
  4.             let maxChildLength = Object.keys(defaultData[0].children[0]).length; 
  5.             for (let i = 0; i < defaultData.length; i++) { 
  6.                 for (let j = 0; j < defaultData[i].children.length; j++) { 
  7.                     const currentObjLength = Object.keys(defaultData[i].children[j]).length; 
  8.                     if (currentObjLength > maxChildLength) { 
  9.                         maxChildLength = currentObjLength; 
  10.                     } 
  11.                 } 
  12.             } 
  13.  
  14.             // 補齊缺少的節(jié)點 
  15.             for (let i = 0; i < defaultData.length; i++) { 
  16.                 for (let j = 0; j < defaultData[i].children.length; j++) { 
  17.                     const currentObjLength = Object.keys(defaultData[i].children[j]).length; 
  18.                     // 當(dāng)前節(jié)點的長度小于第一個子節(jié)點的長度就補齊 
  19.                     for (let k = currentObjLength; k < maxChildLength; k++) { 
  20.                         defaultData[i].children[j]["rcnr" + k] = {}; 
  21.                     } 
  22.                 } 
  23.             } 
  24.  
  25.             // 如果存在空對象添加位置字段 
  26.             for (let i = 0; i < defaultData.length; i++) { 
  27.                 for (let j = 0; j < defaultData[i].children.length; j++) { 
  28.                     // 獲取每天的時間段對象 
  29.                     const item = defaultData[i].children[j]; 
  30.                     // 獲取所有的key 
  31.                     const keys = Object.keys(item); 
  32.                     // 提取所有的日程字段 
  33.                     for (let k = 1; k < keys.length; k++) { 
  34.                         // 日程為空添加wz字段 
  35.                         if (Object.keys(item[keys[k]]).length <= 1) { 
  36.                             defaultData[i].children[j][keys[k]].wz = k - 1; 
  37.                         } 
  38.                     } 
  39.                 } 
  40.             } 
  41.         } 

監(jiān)聽子窗口關(guān)閉

但點擊單元格做完對應(yīng)的操作后,彈窗關(guān)閉,此時我們需要在當(dāng)前頁面監(jiān)聽到子窗口關(guān)閉,然后向后臺請求接口重新獲取數(shù)據(jù)渲染頁面,在打開的彈窗中提供了一個方法,可以調(diào)用父頁面的方法,但是這個方法必須寫在hooks外面他才能獲取到。

此時,問題就產(chǎn)生了,如果寫在hooks外面,那么就無法拿到antd表格內(nèi)部的數(shù)據(jù)做到頁面重新渲染,經(jīng)過一番思考后,想到了可以Proxy來實現(xiàn),當(dāng)被代理的對象發(fā)生改變時,就觸發(fā)hooks里的代理函數(shù),實現(xiàn)代碼如下:

  1. <script type="text/babel"
  2.       // 聲明代理變量 
  3.     let pageStateEngineer; 
  4.     // 需要進行代理的對象 
  5.     let pageState = { status: false }; 
  6.     // 監(jiān)聽子頁面關(guān)閉,彈窗頁面在關(guān)閉時可調(diào)用這個方法,觸發(fā)頁面刷新 
  7.     const getSubpageData = (status) => { 
  8.         console.log("子頁面關(guān)閉"); 
  9.         pageStateEngineer.status = true
  10.     }; 
  11.     const App = () => { 
  12.         // 代理處理函數(shù) 
  13.         const pageStateHandler = { 
  14.             setfunction(recObj, key, value) { 
  15.                 // 表格狀態(tài)改為正在加載 
  16.                 setTableLoadingStatus(true); 
  17.                 // 重新請求接口,獲取最新數(shù)據(jù) 
  18.                 axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  19.                 }).then(function(res) { 
  20.                     // 數(shù)據(jù)請求成功,改變表格加載層狀態(tài) 
  21.                     setTableLoadingStatus(false); 
  22.                     if (res.status === 200) { 
  23.                         // 執(zhí)行表格數(shù)據(jù)渲染函數(shù) 
  24.                         tableDataRendering(res); 
  25.                     } else { 
  26.                         alert("服務(wù)器錯誤"); 
  27.                     } 
  28.                 }); 
  29.                 // 修改對象屬性 
  30.                 recObj[key] = value; 
  31.                 return true
  32.             } 
  33.         }; 
  34.          
  35.         // 第一次渲染時,在借口調(diào)用成功后創(chuàng)建proxy 
  36.         React.useEffect(() => { 
  37.             // 調(diào)用接口獲取表格數(shù)據(jù) 
  38.             axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  39.                 ls: 0, 
  40.                 ts: 0 
  41.             }).then(function(res) { 
  42.                 //創(chuàng)建代理,監(jiān)聽pageState對象改變,pageStateHandler處理變更 
  43.                 pageStateEngineer = new Proxy(pageState, pageStateHandler); 
  44.             }) 
  45.         } 
  46.     } 
  47. </script> 

 

重新渲染表格

用戶在使用日程表時,他會執(zhí)行刪除某個日程,此時表格渲染函數(shù)就要從columns和dataSource中各刪除一條數(shù)據(jù)了,一開始我是直接覆蓋其數(shù)據(jù),這樣做引用地址沒變,就引發(fā)了動態(tài)增加列的那個bug,antd監(jiān)聽不到引用地址改變沒有刷新頁面。但是我又不知道用戶具體刪了哪條數(shù)據(jù),不好自己寫函數(shù)去處理。

經(jīng)過一番求助后,得到了三個解決方案:

  • 使用immer來解決這個問題,經(jīng)過折騰后還是沒實現(xiàn),他返回的數(shù)組是只讀的,antd無法對數(shù)據(jù)進行操作,故放棄。
  • 使用use-immer來替代React的useState來解決這個問題,這個就比較坑爹了,官方提供了umd的js庫,但是通過cdn引入進來后,我硬是沒找到它暴露出來的對象是哪個,沒法用,故放棄。
  • 使用lodash的cloneDeep方法進行深拷貝讓其引用地址改變,這樣antd就能監(jiān)聽到數(shù)據(jù)改變,從而觸發(fā)頁面刷新。

三個解決方案,經(jīng)過驗證后,只有第三個是可行的,于是我采取了它,實現(xiàn)代碼如下:

  1. const App = () => { 
  2.         // 表格列格式定義 
  3.         const defaultColumns = [ 
  4.             { 
  5.                 dataIndex: "rq"
  6.                 title: "日期"
  7.                 align: "center"
  8.                 fixed: "left"
  9.                 colSpan: 2, 
  10.                 width: 140.5, 
  11.                 className: "rqfontSet"
  12.                 onCell: dateHandle, 
  13.                 render: (value, item, index) => {} 
  14.             }, 
  15.             { 
  16.                 dataIndex: "sjd"
  17.                 title: "時間段"
  18.                 width: 70, 
  19.                 colSpan: 0, 
  20.                 fixed: "left"
  21.                 align: "center"
  22.                 className: "sjdfontSet"
  23.                 render: (value, item, index) => { 
  24.                     let v1 = value.charAt(0); 
  25.                     let v2 = value.charAt(1); 
  26.                     return <div>{v1}<br />{v2}</div>; 
  27.                 } 
  28.             } 
  29.         ]; 
  30.  
  31.         // 表格數(shù)據(jù)渲染函數(shù) 
  32.         const tableDataRendering = function(res) { 
  33.           // 根據(jù)日程列字段數(shù)據(jù)賦值表格列的日程字段,rcList中包含sjd所以需要1開始 
  34.             for (let i = 1; i < rcList.length; i++) { 
  35.                 let rcnr = { 
  36.                     dataIndex: rcList[i], 
  37.                     title: "日程內(nèi)容" + i, 
  38.                     align: "left"
  39.                     width: 189.5, 
  40.                     className: "rcnrfontSet"
  41.                     onCell: tdSet, 
  42.                     render: rctd_render 
  43.                 }; 
  44.                 defaultColumns.push(rcnr); 
  45.             } 
  46.  
  47.             // 渲染表格數(shù)據(jù) 
  48.             handleData(defaultData); 
  49.             // 渲染表格列,使用cloneDeep進行深拷貝,觸發(fā)useState的更新 
  50.             setColumns(_.cloneDeep(defaultColumns)); 
  51.         } 
  52.      // 計算要合并的列數(shù) 
  53.         const handleData = (data) => { 
  54.             if (data == null) { 
  55.                 data = defaultData; 
  56.             } 
  57.             let newArr = []; 
  58.             data.map(item => { 
  59.                 if (item.children) { 
  60.                     item.children.forEach((subItem, i) => { 
  61.                         let obj = { ...item }; 
  62.                         Object.assign(obj, subItem); 
  63.                         delete obj.children; 
  64.                         obj.rowLength = item.children.length; 
  65.                         newArr.push(obj); 
  66.                     }); 
  67.                 } 
  68.             }); 
  69.             // console.log("處理好的表格數(shù)據(jù)"); 
  70.             // console.log(newArr); 
  71.             // 將處理好的數(shù)據(jù)放入optRecords,使用cloneDeep進行深拷貝,觸發(fā)useState的更新 
  72.             setOptRecords(_.cloneDeep(newArr)); 
  73.         }; 
  74.   } 

還有一種解決方案是使用JSON.parse進行深拷貝,但是這種深拷貝有個問題:但json數(shù)據(jù)中有函數(shù)時,里面的函數(shù)會失效沒法執(zhí)行,由于我需要自定義antd的表格,在json數(shù)據(jù)中包含了函數(shù),因此我不能使用這個方法。

觸頂/觸底加載數(shù)據(jù)

由于業(yè)務(wù)需要,不能使用antd的分頁功能,需要實現(xiàn)觸頂向前加載30條數(shù)據(jù),觸底向后加載30條數(shù)據(jù)。總共只能加載3個月的數(shù)據(jù)。

實現(xiàn)代碼如下:

 

這里需要比較坑的地方就是如果觸頂/觸底時,拖動橫向滾動也會觸發(fā)滾動監(jiān)聽,因此我們需要排除橫向滾動事件。

  1. <script type="text/babel"
  2.     // 觸頂數(shù)據(jù)起始條數(shù) 
  3.     let dataToppingStartNum = 0; 
  4.     // 觸底數(shù)據(jù)起始條數(shù) 
  5.     let dataBottomOutStartNum = 30; 
  6.     // 橫向/垂直滾動條起始位置 
  7.     let levelPosition; 
  8.     let verticalPosition; 
  9.     // 觸底/觸頂次數(shù) 
  10.     let topFrequency = 0; 
  11.     let bottomFrequency = 0; 
  12.     const App = () => { 
  13.         // 橫向滾動條位置 
  14.         levelPosition = document.querySelector(".ant-table-body").scrollLeft; 
  15.         // 縱向滾動條位置 
  16.         verticalPosition = document.querySelector(".ant-table-body").scrollTop; 
  17.         // 獲取表格容器 
  18.         let antdTable = document.querySelector(".ant-table-body"); 
  19.         //頁面滾動監(jiān)聽 
  20.         antdTable.onscroll = function() { 
  21.             // 觸底向后加載數(shù)據(jù) 
  22.             if (antdTable.scrollTop + antdTable.clientHeight >= antdTable.scrollHeight) { 
  23.                 // 判斷是否橫向滾動 
  24.                 if (antdTable.scrollLeft !== levelPosition) { 
  25.                     // 更新位置 
  26.                     levelPosition = antdTable.scrollLeft; 
  27.                     return false
  28.                 } 
  29.                 // 第一次觸底不觸發(fā)數(shù)據(jù)加載 
  30.                 if (bottomFrequency === 0) { 
  31.                     bottomFrequency++; 
  32.                     return false
  33.                 } 
  34.                 if (bottomFrequency > 0) { 
  35.                     bottomFrequency = 0; 
  36.                 } 
  37.                 dataBottomOutStartNum += 30; 
  38.                 // 判斷已加載的數(shù)據(jù) 
  39.                 if (dataBottomOutStartNum > 90) { 
  40.                     alert("最多只能向后加載90天的數(shù)據(jù)"); 
  41.                     return false
  42.                 } 
  43.                 // 保留向上滑動的天數(shù) 
  44.                 let bottomTS = 0; 
  45.                 // 頁面第一次向上滑動,修改位置 
  46.                 if (dataToppingStartNum !== 0) { 
  47.                     bottomTS = -30; 
  48.                 } 
  49.                 setTableLoadingStatus(true); 
  50.                 axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  51.                     ts: bottomTS, 
  52.                     ls: dataBottomOutStartNum 
  53.                 }).then(function(res) { 
  54.                     // 數(shù)據(jù)請求成功,改變表格加載層狀態(tài) 
  55.                     setTableLoadingStatus(false); 
  56.                     if (res.status === 200) { 
  57.                         // 執(zhí)行表格數(shù)據(jù)渲染函數(shù) 
  58.                         tableDataRendering(res); 
  59.                     } else { 
  60.                         alert("服務(wù)器錯誤"); 
  61.                     } 
  62.                 }); 
  63.             } 
  64.  
  65.             // 觸頂向前加載數(shù)據(jù) 
  66.             if (antdTable.scrollTop === 0) { 
  67.                 // 判斷是否橫向滾動 
  68.                 if (antdTable.scrollLeft !== levelPosition) { 
  69.                     // 更新位置 
  70.                     levelPosition = antdTable.scrollLeft; 
  71.                     return false
  72.                 } 
  73.                 // 第一次觸頂不觸發(fā)數(shù)據(jù)加載 
  74.                 if (topFrequency === 0) { 
  75.                     topFrequency++; 
  76.                     return false
  77.                 } 
  78.                 if (topFrequency > 0) { 
  79.                     topFrequency = 0; 
  80.                 } 
  81.                 dataBottomOutStartNum += 30; 
  82.                 if (dataBottomOutStartNum > 90) { 
  83.                     alert("最多只能向前加載90天的數(shù)據(jù)"); 
  84.                     return false
  85.                 } 
  86.                 dataToppingStartNum -= 30; 
  87.                 setTableLoadingStatus(true); 
  88.                 axios.post('http://mock-api.com/mnE66LKJ.mock/getTableListData', { 
  89.                     ts: dataToppingStartNum, 
  90.                     ls: dataBottomOutStartNum 
  91.                 }).then(function(res) { 
  92.                     // 數(shù)據(jù)請求成功,改變表格加載層狀態(tài) 
  93.                     setTableLoadingStatus(false); 
  94.                     if (res.status === 200) { 
  95.                         // 執(zhí)行表格數(shù)據(jù)渲染函數(shù) 
  96.                         tableDataRendering(res); 
  97.                     } else { 
  98.                         alert("服務(wù)器錯誤"); 
  99.                     } 
  100.                 }); 
  101.             } 
  102.         } 
  103.     } 
  104. </script> 

這里需要比較坑的地方就是如果觸頂/觸底時,拖動橫向滾動也會觸發(fā)滾動監(jiān)聽,因此我們需要排除橫向滾動事件。

責(zé)任編輯:武曉燕 來源: 神奇的程序員k
相關(guān)推薦

2011-03-17 13:09:45

Ubuntu 11.1

2013-05-03 09:27:36

Ubuntu 13.1

2009-12-16 10:41:47

Android日程表

2009-09-29 13:32:40

Ubuntu 9.10Linux操作系統(tǒng)發(fā)布日程表

2013-09-09 15:38:13

Fedora 20Fedora操作系統(tǒng)

2009-03-05 08:30:57

LinuxUbuntu日程表

2021-03-21 20:23:07

樹莓派Linux

2009-03-23 07:36:43

Ubuntu 9.10win7正式版

2017-03-16 14:01:00

2011-06-02 09:58:09

CentOS 6.0

2015-10-29 11:36:45

Google技術(shù)經(jīng)理程序員

2022-09-22 12:38:46

antd form組件代碼

2010-04-07 11:44:40

Ubuntu 10.1

2025-03-24 00:00:00

2022-07-06 08:29:12

antdInput 組件

2009-12-21 17:53:45

Fedora Core

2015-05-11 17:21:33

Google IO2015

2021-05-12 09:07:09

Java數(shù)據(jù)結(jié)構(gòu)算法

2011-06-16 09:25:17

Firefox 5.0

2009-10-12 10:01:17

服務(wù)器故障
點贊
收藏

51CTO技術(shù)棧公眾號

亚洲第一福利视频| 一区二区在线看| 国产精品电影观看| 老司机福利在线观看| 在线免费成人| 亚洲va韩国va欧美va| 欧美高清视频一区| 一级特黄色大片| 狠狠久久婷婷| 在线视频免费一区二区| 师生出轨h灌满了1v1| 国产免费不卡| 一区二区三区在线视频免费| 久久国产精品免费一区| 国产孕妇孕交大片孕| 国产精品v亚洲精品v日韩精品 | 国模精品一区| 日韩一级免费观看| 热久久精品免费视频| 在线āv视频| 久久综合国产精品| 999国产在线| 欧美日韩在线视频播放| 在线不卡亚洲| www.日韩系列| 中文字幕 自拍| 国产精品玖玖玖在线资源| 欧美男女性生活在线直播观看| 毛片在线视频播放| 欧美亚洲天堂| 一区二区中文视频| 欧洲精品一区色| 五月婷婷在线播放| 国内精品国产三级国产a久久| 国产精品91在线观看| 日韩av在线天堂| 国产精品草草| 欧美美女操人视频| 成人免费毛片xxx| 国产真实有声精品录音| 亚洲女人被黑人巨大进入| youjizz.com国产| 永久免费精品视频| 日韩午夜激情免费电影| 在线观看国产福利| 日韩专区视频| 欧美日韩一区二区三区在线| 成人午夜视频免费在线观看| 草草影院在线| 亚洲国产sm捆绑调教视频| 好色先生视频污| 成人一级生活片| 99久久久久成人国产免费 | 色乱码一区二区三区在线| 日韩伦理在线| 夜夜嗨av一区二区三区网页| www.-级毛片线天内射视视| 米奇777四色精品人人爽| 国产精品久久影院| 吴梦梦av在线| 2020国产在线视频| 亚洲综合丁香婷婷六月香| 欧美交换配乱吟粗大25p| 91亚洲天堂| 一区二区免费看| 夜夜添无码一区二区三区| 变态调教一区二区三区| 亚洲成a人v欧美综合天堂| 国产成人无码a区在线观看视频| 少妇在线看www| 日韩欧美精品免费在线| 久久久精品三级| 欧美天堂一区| 日韩欧美aaaaaa| 无码精品一区二区三区在线播放| 午夜欧洲一区| 伊是香蕉大人久久| 天天色天天综合| 国产精品豆花视频| 午夜精品视频网站| 无码人妻精品一区二区三区蜜桃91| 日本怡春院一区二区| 91精品久久久久久久| www.日韩高清| 久久综合久久99| 亚洲精品国产精品国自产观看| 国产日产一区二区| 午夜精品久久久久久久久| 精品国产成人av在线免| 日本国产一区| 亚洲成在人线av| 久久久久久国产免费a片| 日韩在线看片| 国外成人免费在线播放| 日本黄色中文字幕| 国产a区久久久| 欧洲在线视频一区| 中文字幕在线观看网站| 一本大道综合伊人精品热热| 日韩在线一区视频| 欧美成人午夜77777| 中文字幕日韩欧美| 久久精品国产亚洲av无码娇色| 久久精品女人天堂| 99久久99久久精品国产片| 色网站在线免费观看| 中文字幕亚洲精品在线观看| 三上悠亚久久精品| 日韩毛片免费看| 日韩电影大全免费观看2023年上| 亚洲av无一区二区三区| 亚洲茄子视频| 亚洲bt欧美bt日本bt| 久久天堂电影| 亚洲国产裸拍裸体视频在线观看乱了| 美女网站视频黄色| 日韩成人动漫在线观看| 欧美大奶子在线| 真实的国产乱xxxx在线91| www.亚洲在线| 日韩视频 中文字幕| aaaa欧美| 亚洲欧美自拍一区| 亚洲一区欧美在线| 国产精品亚洲第一| 综合久久国产| 欧美与亚洲与日本直播| 日韩成人黄色av| 久久精品www| 国产在线不卡一区| 亚洲一区二区三区色| gay欧美网站| 精品视频久久久久久久| 精品无码m3u8在线观看| 国产美女视频91| 在线观看免费91| 成人午夜一级| 亚洲一区二区黄| 九九热精品视频在线| av亚洲精华国产精华精华| 中文字幕人妻熟女人妻洋洋| 成人免费91| 日韩视频一区在线| 在线观看av大片| 国产精品色哟哟网站| 爱情岛论坛成人| 成人在线免费观看网站| 国产成人一区二| 国产在线你懂得| 欧美性猛片aaaaaaa做受| 中文字幕 自拍| 日韩电影免费一区| 亚洲精品高清国产一线久久| 丰满少妇一区| 久久天天躁日日躁| 99热这里只有精品在线观看| 亚洲欧美激情一区二区| 一级日本黄色片| 午夜久久美女| 国产精品久久国产精品| 国模雨婷捆绑高清在线| 亚洲第一精品福利| 日韩av综合在线| 久久免费电影网| 久久久国产欧美| 香蕉视频国产精品| 高清国语自产拍免费一区二区三区| 麻豆福利在线观看| 日韩av最新在线观看| 无码一区二区三区在线观看| 欧美国产日韩在线观看| 亚洲欧美自偷自拍另类| 亚洲综合自拍| 国产日韩在线一区二区三区| 中文在线а√天堂| 爽爽爽爽爽爽爽成人免费观看| 91精品国产乱码久久| 一区二区三区四区在线播放 | 成年人精品视频| 狠狠躁夜夜躁av无码中文幕| 欧美日韩午夜激情| 正在播放国产对白害羞| 国产一区二区三区黄视频 | av在线网页| 国产午夜精品视频| 国产口爆吞精一区二区| 亚洲高清不卡在线观看| 国产手机在线观看| 国内成人精品2018免费看| 91黄色在线看| 精品午夜久久| 97在线中文字幕| 电影一区二区三| 久久久av网站| 亚洲三区在线观看无套内射| 欧美日韩一区高清| 日本一级淫片色费放| 国产精品女主播av| 这里只有精品在线观看视频| 日本亚洲视频在线| 毛片在线视频观看| 日韩精品欧美| 精品欧美一区二区三区久久久| 国产激情欧美| 2021国产精品视频| 伊人影院蕉久影院在线播放| 亚洲天堂成人在线视频| www.日韩在线观看| 欧美性感一类影片在线播放| 国产在线观看99| 国产精品久久久久久久第一福利 | 99久久免费精品高清特色大片| 手机在线免费观看毛片| 在线播放精品| 日本xxxxx18| 日韩av在线播放网址| 国内精品国语自产拍在线观看| 一区二区三区| 日韩美女在线看| 丁香花在线观看完整版电影| 久久精品亚洲94久久精品| 视频二区在线| 精品成人免费观看| 国产强伦人妻毛片| 欧美撒尿777hd撒尿| 国产高潮久久久| 亚洲国产精品久久人人爱| 欧美特黄一级片| 欧美国产欧美亚州国产日韩mv天天看完整 | 久久亚洲风情| 久久国产精品网| 手机在线观看日韩av| 国产一区二区三区四区| 国产在线精品一区| 日韩三级精品| 亚洲r级在线观看| 日韩大陆av| 国产美女被下药99| 巨胸喷奶水www久久久免费动漫| 2019中文字幕在线观看| 91桃色在线| 午夜精品在线视频| а√天堂8资源中文在线| 久久久久久久999| 欧美亚洲天堂| 97精品免费视频| 91豆花视频在线播放| 国模吧一区二区| 国产污视频在线播放| 91爱视频在线| 国偷自产一区二区免费视频| 欧美一级片在线播放| 悠悠资源网亚洲青| 欧美专区中文字幕| **在线精品| 国产精品黄页免费高清在线观看| 亚洲欧美在线成人| 国产精品亚洲自拍| 综合久久av| 91文字幕巨乱亚洲香蕉| 一区二区三区四区精品视频| 国产精品免费一区二区三区在线观看 | 欧美成人直播| 只有这里有精品| 欧美体内she精视频在线观看| 国产片侵犯亲女视频播放| 亚洲区一区二| 免费在线观看的毛片| 久久se这里有精品| 激情小说欧美色图| 99国产欧美另类久久久精品| 黄瓜视频污在线观看| 国产欧美精品一区二区三区四区 | 亚洲精品日产精品乱码不卡| 青娱乐国产在线视频| 亚洲成人动漫一区| 久久精品视频5| 欧美猛男超大videosgay| www.av日韩| 日韩精品免费在线播放| 岛国在线视频| 欧美精品在线网站| 在线天堂新版最新版在线8| 国产精品久久久久7777婷婷| 久久久国产精品入口麻豆| 国新精品乱码一区二区三区18| 九一国产精品| 伊人再见免费在线观看高清版| 亚洲欧美日韩在线观看a三区| 老司机久久精品| av一区二区三区四区| 日本免费www| 亚洲国产成人91porn| 中文天堂在线视频| 日韩欧美三级在线| 国产在线观看高清视频| 欧美裸身视频免费观看| 一二区成人影院电影网| 国产91免费视频| 久久国产影院| 无码精品a∨在线观看中文| 黄色日韩网站视频| 一区二区三区免费在线观看视频| 国产精品夫妻自拍| 国产又爽又黄的视频| 91精品国产丝袜白色高跟鞋| 日本一卡二卡四卡精品| 欧美另类极品videosbestfree| 裤袜国产欧美精品一区| 99热国产免费| 久久激情电影| 久久无码高潮喷水| 国产精品伊人色| 精品手机在线视频| 精品久久久久久| 国产白浆在线观看| 深夜福利91大全| 深夜视频一区二区| 欧美少妇一区| 99香蕉国产精品偷在线观看 | 99久久精品国产一区| 顶臀精品视频www| 在线观看免费成人| 亚洲色图另类小说| 欧美激情区在线播放| 91成人app| 亚洲一区二区四区| 日产国产高清一区二区三区| 亚洲区免费视频| 福利微拍一区二区| 天天操天天射天天舔| 欧美国产精品va在线观看| 精品一区二区三区中文字幕视频 | 五月开心播播网| 亚洲线精品一区二区三区| 国产黄色免费大片| 久久av在线播放| 粉嫩一区二区三区在线观看| 亚洲成人在线视频网站| 久热精品视频| 国产精品密蕾丝袜| 色婷婷亚洲婷婷| 久草视频视频在线播放| 欧洲精品在线视频| 美女毛片一区二区三区四区| 成人一对一视频| 97se亚洲国产综合自在线观| 男人的天堂一区| 日韩电影第一页| 黑人巨大精品| 日韩亚洲视频在线| 日韩电影在线观看电影| 韩国三级hd中文字幕| 欧美性猛片xxxx免费看久爱| av在线第一页| 国产日本欧美视频| 五月天激情综合网| 美日韩精品视频免费看| 亚洲男人天堂网址| 亚洲欧美日韩天堂| 美女色狠狠久久| 综合久久国产| 国产成a人亚洲精| 日韩黄色三级视频| 国产亚洲精品日韩| 日本黄色成人| 日本男女交配视频| 91免费小视频| 中文在线观看av| 美女黄色丝袜一区| 国产精品调教视频| 欧美 国产 小说 另类| 中文字幕精品—区二区四季| 国产又大又黄又爽| 欧美精品第一页在线播放| 理论片一区二区在线| 久久午夜夜伦鲁鲁一区二区| 国产精品另类一区| 国精产品乱码一区一区三区四区| 午夜精品一区二区三区在线播放| 深爱激情久久| 国产一区二区在线观看免费视频| 亚洲一区在线看| 国产一级在线观看| 亚洲精品欧美日韩| 99伊人成综合| 天堂а√在线中文在线鲁大师| 日韩精品中文字幕一区| 久久sese| 国内少妇毛片视频| 国产日韩精品一区| 不卡视频在线播放| 国产极品精品在线观看| 五月天久久777| 久久久亚洲av波多野结衣| 正在播放亚洲一区| 国产伦精品一区二区三区视频金莲| 精品91一区二区三区| 91性感美女视频| 国产a级免费视频|