精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

av激情在线观看| 丰满爆乳一区二区三区| 国产精品久久久久毛片| 伊人成人在线| 亚洲美女视频网| 182午夜视频| 成av人片在线观看www| 久久精品一区二区三区av| 成人两性免费视频| 看片网址国产福利av中文字幕| 国产色在线观看| 成人午夜电影小说| 欧美在线免费视频| 国产喷水在线观看| 天美av一区二区三区久久| 欧美日韩成人在线| 春日野结衣av| 18av在线视频| 欧美高清在线一区| 国产欧美一区二区在线播放| 在线免费a视频| 亚洲永久在线| 九九视频直播综合网| 欧美一区二区三区啪啪| 久久久久久久久久久网站| a级在线观看视频| 粉嫩一区二区三区在线观看| 欧美午夜美女看片| www.激情网| 成人福利在线| 91色porny在线视频| 亚洲自拍欧美色图| 怡红院男人的天堂| 国产欧美日韩亚洲一区二区三区| 91精品久久久久久蜜臀| 精品无码一区二区三区在线| 欧美激情黑人| 久久日一线二线三线suv| 成人av免费看| va视频在线观看| 韩国av一区二区三区| 国产精品久久久久久久av大片| 免费网站在线高清观看| 都市激情久久| 日韩欧美国产成人一区二区| 91精产国品一二三产区别沈先生| 欧美家庭影院| 亚洲精品综合在线| 亚洲欧洲日本在线| 国产成人女人毛片视频在线| av免费在线不卡| 精品一区二区三区日韩| 国产精品一区久久久| 综合久久中文字幕| 日日摸夜夜添夜夜添亚洲女人| 日韩中文在线视频| 丁香激情五月少妇| 日韩精品久久久久久久电影99爱| 69堂精品视频| 天天操夜夜操很很操| 国产精品视频首页| 欧美xxxxxxxx| 日本少妇xxxx| 婷婷激情久久| 亚洲午夜精品视频| eeuss中文字幕| 91久久电影| 粗暴蹂躏中文一区二区三区| 黄色一级视频免费| 亚洲乱码视频| 国产成人久久久精品一区| 不卡一卡二卡三乱码免费网站| 日韩欧美区一区二| 一个人看的视频www| 国产精品日韩精品在线播放 | 奇米网一区二区| 清纯唯美综合亚洲| 久久九九热免费视频| 放荡的美妇在线播放| 国内综合精品午夜久久资源| 国产91|九色| 中文字幕无线码一区| 国产一区二区网址| 久久99精品久久久久久青青日本| 国产又爽又黄免费软件| 国产成人综合网| 精品伦精品一区二区三区视频| 99久久99久久久精品棕色圆| 国产成人av一区二区三区在线| 国产日韩精品电影| 午夜精品久久久久久久99老熟妇| 三级成人黄色影院| 日韩精品麻豆| 色噜噜狠狠色综合中国| av免费在线播放网站| 午夜不卡一区| 亚洲第一免费播放区| 久久国产柳州莫菁门| 在线中文字幕亚洲| 国产91精品久久久久| 国产女优在线播放| 成人一道本在线| 视频一区视频二区视频三区视频四区国产| 神马一区二区三区| 久久综合久久综合亚洲| 97超碰免费观看| 五月天av在线| 欧美一二三区在线| 色噜噜日韩精品欧美一区二区| 性人久久久久| 日韩视频精品在线| 在线视频一区二区三区四区| 狠狠狠色丁香婷婷综合久久五月| 国产中文字幕91| 无套内谢的新婚少妇国语播放| 成人美女视频在线观看| 亚洲精品人成| 亚洲优女在线| 日韩欧美视频一区| 国产馆在线观看| 久久高清免费观看| 国产精品久久久久久久久久久久午夜片| 精品人妻aV中文字幕乱码色欲| 国产曰批免费观看久久久| 欧美精品国产精品久久久| 国产高清在线a视频大全| 欧美日韩国产在线观看| 国产精品亚洲无码| 亚洲日韩成人| 国产精品久久久久久久久久久久午夜片 | 捆绑裸体绳奴bdsm亚洲| 午夜国产一区二区| 国产精品久久久久91| 午夜av免费观看| 亚洲一区二区三区爽爽爽爽爽| 欧美精品久久久久久久久久久| 97成人在线免费视频| 色大18成网站www在线观看| 狠狠久久亚洲欧美专区| 色姑娘综合天天| 亚洲精品2区| 成人淫片在线看| 色综合久久影院| 欧美日韩在线免费视频| 精品人妻无码一区| 久久一区激情| 欧日韩一区二区三区| 天堂在线中文网官网| 亚洲精品少妇网址| 中文字幕在线观看视频网站| av毛片久久久久**hd| 国产精品网站免费| 私拍精品福利视频在线一区| 91精品国产高清自在线看超| 五月婷婷丁香网| 午夜日韩在线电影| av无码一区二区三区| 妖精视频成人观看www| 国产手机精品在线| av免费在线免费| 欧美xxxxxxxx| 圆产精品久久久久久久久久久| 蜜臀久久99精品久久久久宅男| 亚洲自拍偷拍色片视频| а√中文在线8| 日韩精品在线一区二区| 亚洲激情视频一区| 91色porny在线视频| 黄色av免费在线播放| 青草国产精品| 91麻豆蜜桃| 超碰91在线观看| 亚洲免费影视第一页| 亚洲欧美一二三区| 中文字幕一区二区三| 亚洲天堂小视频| 国产日韩1区| 婷婷五月色综合| 一区二区三区亚洲变态调教大结局| 成人午夜视频网站| 日韩av中文字幕在线免费观看| 亚洲v在线观看| 国产视频一区欧美| 日本一区精品| 日韩高清在线观看一区二区| 欧美一级黄色网| 欧美成人三区| 亚洲国产精品久久| 中文字幕+乱码+中文乱码91| 一区二区高清视频在线观看| 精品人妻一区二区三区香蕉| 九一久久久久久| 少妇av一区二区三区无码| 成人6969www免费视频| 国产在线精品播放| 看黄在线观看| 久热国产精品视频| 亚洲区小说区图片区| 欧美精品在线观看一区二区| 日韩网红少妇无码视频香港| 中文字幕久久午夜不卡| 婷婷五月精品中文字幕| 蜜桃视频在线观看一区| 免费毛片网站在线观看| 婷婷亚洲图片| 欧美一区观看| 91麻豆精品激情在线观看最新 | 日韩精品无码一区二区三区| 亚洲人成777| 国模叶桐国产精品一区| 在线国产情侣| 精品视频中文字幕| 国产丰满美女做爰| 欧美日韩精品一区二区三区| 一级免费在线观看| 一区二区三区在线视频观看58| 亚洲妇女无套内射精| 久久久久.com| 国产精品12345| 欧美jjzz| 在线看成人av电影| 精品福利久久久| 精品国产一区二区三| 欧美经典影片视频网站| 国产精品女人久久久久久| 天堂av在线网| 97色在线视频| 超碰高清在线| 国外成人在线播放| 欧美78videosex性欧美| 俺去了亚洲欧美日韩| 成人高清网站| 一区二区在线视频| 你懂的在线播放| 亚洲黄页视频免费观看| 性欧美一区二区三区| 欧美日高清视频| 亚洲天堂999| 精品视频全国免费看| 中文字幕免费高清网站| 91久久线看在观草草青青| 香蕉影院在线观看| 色哟哟日韩精品| 亚洲 日本 欧美 中文幕| 欧美视频在线视频| 国产精品视频一区在线观看| 日韩欧美在线中文字幕| 一级片免费在线播放| 91久久人澡人人添人人爽欧美| 欧美成人免费观看视频| 最新欧美精品一区二区三区| 综合 欧美 亚洲日本| 国产精品三级视频| 黄色一级大片在线免费观看| ●精品国产综合乱码久久久久| 这里只有精品在线观看视频| 懂色av一区二区三区免费看| 日本少妇xxxx软件| 不卡av在线免费观看| 国产又爽又黄无码无遮挡在线观看| 韩国精品一区二区| 亚洲一区二区图片| 国产成a人无v码亚洲福利| 国产女主播在线播放| 99精品久久免费看蜜臀剧情介绍| 日韩成人av免费| 狠狠色狠狠色综合日日91app| 88av.com| 久久激五月天综合精品| 亚洲午夜精品在线观看| 波多野结衣中文字幕一区二区三区 | 黄色片子在线观看| 亚洲精品日韩综合观看成人91| 色欲AV无码精品一区二区久久| 国产69精品久久久久777| 国产xxx在线观看 | youjizz.com国产| 99久久精品免费看| 婷婷色一区二区三区| 亚洲图片欧美激情| 日本中文字幕在线免费观看| 色先锋资源久久综合| 91theporn国产在线观看| 日韩精品一区二区三区视频| 日本黄视频在线观看| 在线不卡国产精品| 日本资源在线| 日本午夜精品理论片a级appf发布| 98色花堂精品视频在线观看| 国产成人jvid在线播放| 国产一区二区三区免费观看在线| 国产精品日韩在线| 亚洲国产精品免费视频| 久久国产精品99久久久久久丝袜| 精品国内亚洲2022精品成人| 日韩亚洲视频在线| 国产一区二区三区四区三区四| 在线观看成人免费| 日韩一级欧洲| 中文字幕66页| 91蜜桃婷婷狠狠久久综合9色| 国产一级二级在线观看| 国产精品久久777777| 91在线看视频| 欧美一区二区三级| 黄色在线免费观看大全| 欧美黑人巨大xxx极品| 91p九色成人| 久久99久久99精品蜜柚传媒| 婷婷精品进入| 中文字幕一区二区三区四区在线视频 | 日韩一区二区av| 岛国av免费在线观看| 成人福利网站在线观看11| 希岛爱理av免费一区二区| 特大黑人娇小亚洲女mp4| 天堂久久一区二区三区| 美女黄色一级视频| 亚洲精品乱码久久久久久久久| 日韩在线中文字幕视频| 在线视频一区二区免费| 天堂网av在线播放| 欧美激情a∨在线视频播放| 日韩成人在线电影| 日本一区二区三区在线视频 | 无码人妻精品一区二区三区在线| 亚洲伦理精品| 人妻互换一二三区激情视频| 自拍偷拍欧美精品| 中文天堂在线资源| 亚洲欧美日韩久久久久久| 欧美伦理91| 九色91国产| 亚洲欧美成人综合| 日本一区二区在线观看视频| 亚洲自拍偷拍九九九| 国产熟女一区二区三区五月婷 | 波多野结衣在线影院| 69影院欧美专区视频| 加勒比久久高清| 国产69精品久久久久久久| 99麻豆久久久国产精品免费| 久久精品这里有| 亚洲成av人影院在线观看| 欧美黄色视屏| 精品国产乱码久久久久软件| 欧美三级不卡| 国产a√精品区二区三区四区| 日本一区二区三级电影在线观看 | 欧美精品观看| 欧美性猛交xx| 亚洲一区在线看| 黄色一级大片在线免费看国产| 亚洲性av在线| 成人午夜亚洲| 国产高潮呻吟久久久| 狠狠狠色丁香婷婷综合激情| 欧美人妻精品一区二区三区| 日韩久久免费av| 国产直播在线| 日本一区二区三区免费看| 蜜桃传媒麻豆第一区在线观看| 在线看黄色的网站| 婷婷中文字幕一区三区| 色av男人的天堂免费在线| 日韩av日韩在线观看| 日韩精品一卡| 午夜免费视频网站| 亚洲国产色一区| 久久99久久| 国产欧美在线观看| 欧美日韩免费| 中文字幕乱码在线| 色哟哟在线观看一区二区三区| 天天操天天爱天天干| 日本精品久久电影| 色婷婷热久久| 国产51自产区| 色综合久久天天综合网| 欧美日韩视频在线播放| 91亚色免费| 国产视频一区欧美| 91免费在线看片| 精品国产一区二区三区av性色| yellow91字幕网在线| 国产精品久久久久久久小唯西川 | 在线观看的毛片| 亚洲精品国久久99热| 香港三日本三级少妇66| 国产欧美在线看| 免费亚洲网站| 国产午夜手机精彩视频| 亚洲丁香婷深爱综合| 久久69成人| 国产91在线免费| 亚洲精品国产精华液| 免费av在线电影| 成人免费视频观看视频| 日韩成人精品视频| 国产乡下妇女做爰|