最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React.js組件實(shí)現(xiàn)拖拽排序組件功能過程解析

 更新時(shí)間:2020年04月27日 09:05:04   作者:白眉少俠  
這篇文章主要介紹了React.js組件實(shí)現(xiàn)拖拽排序組件功能過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

因?yàn)槭褂昧藃eact.js技術(shù)棧,所以封裝優(yōu)先考慮輸入和輸出?;跀?shù)據(jù)驅(qū)動(dòng)去渲染頁(yè)面、控制拖拽元素的順序。

由于我不考慮兼容IE8等舊版本瀏覽器,拖拽的效果采用了HTML5的拖放(Drag 和 drop)。當(dāng)然,如果要求兼容性豐富,使用鼠標(biāo)點(diǎn)擊的相關(guān)事件也很簡(jiǎn)單。

實(shí)現(xiàn)的效果如下:

第一步是先了解H5拖放的相關(guān)屬性,MDN上有詳細(xì)的說(shuō)明,鏈接

有一點(diǎn)需要注意的是,react.js會(huì)給所有的屬性事件名稱前加上"on",后面則為駝峰式寫法。例如原生的click事件,在react.js里應(yīng)使用onClick事件。

我的組件使用的拖放屬性如下:

  • draggable 當(dāng)設(shè)置為true時(shí),當(dāng)前控件可以拖拽
  • onDragStart 控件開始被拖拽時(shí)觸發(fā)的事件,它提供一個(gè)dataTransfer.setData()方法,將必要的數(shù)據(jù)存儲(chǔ)在對(duì)象中便于在其它方法中調(diào)用
  • onDragOver 規(guī)定當(dāng)前控件可以接收拖拽的組件的方法,一般在此方法中阻止冒泡
  • onDragEnter 拖動(dòng)后鼠標(biāo)進(jìn)入另一個(gè)可接受區(qū)域時(shí)觸發(fā),通過它可以實(shí)現(xiàn)移入效果
  • onDragLeave a拖到b,離開b的時(shí)候觸發(fā),可以用于監(jiān)聽消除移入效果的時(shí)機(jī)
  • onDrop 當(dāng)控件被“釋放”到一個(gè)有效的釋放目標(biāo)位置時(shí)觸發(fā),我在這個(gè)方法中處理數(shù)據(jù),并通過它調(diào)用onChange方法,將value值暴露給父組件

其中draggable,onDragStart是被“拖拽”方需要設(shè)置的屬性,onDragOver,onDragEnter,onDragLeave和onDrop是被“拖入”方需要設(shè)置的屬性。不過對(duì)于我的拖拽排序組件,每一個(gè)元素都是拖拽和拖入方

第二步,既然“她"是react.js的組件, 按照習(xí)慣,簡(jiǎn)單的將輸入屬性定為為value,同時(shí),暴露onChange事件監(jiān)聽value的變化,并將其暴露給父組件,同時(shí),暴露一個(gè)屬性sortKey告訴組件使用哪個(gè)key作為排序字段。
既然涉及到排序,同時(shí)允許指定組件每個(gè)元素的內(nèi)部子組件,我將輸入數(shù)據(jù)格式定義為一個(gè)數(shù)組對(duì)象,其中content可以為reactNode:

 value: [
    {
     content: 'div1',
     code: '01',
     sort: 0,
    },
    {
     content: 'div2',
     code: '02',
     sort: 1
    },
    {
     content: 'div3',
     code: '03',
     sort: 2
    },
    {
     content: 'div5',
     code: '05',
     sort: 5
    },
    {
     content: 'div4',
     code: '04',
     sort: 4
    }]

根據(jù)value我去生成可排序組件的每個(gè)node,關(guān)鍵代碼如下:

 // 生成拖拽組件
 createDraggleComponent(data, sortKey, style, uId) {
  return data.sort(this.compare(sortKey)).map((item) => {
   return (
    <div
     className={styles.content}
     key={item.code}
     draggable={true}
     onDragEnter={this.dragenter.bind(this)}
     onDragLeave={this.dragleave.bind(this)}
     onDragStart={this.domdrugstart.bind(this, item[sortKey], item.code, uId, item)}
     onDrop={this.drop.bind(this, item[sortKey], data, sortKey, uId)}
     onDragOver={this.allowDrop.bind(this)}
     style={{ ...style }}>{item.content}</div>
   )
  })
 }
 render() {
  const { value, sortKey, style } = this.props;
  return (
   <Row>
    <div style={{ display: 'flex', flexDirection: 'row' }}>
     {this.createDraggleComponent(value, sortKey, style)}
    </div>
   </Row>
  )
 }

其中的屬性方法具體實(shí)現(xiàn):

 // 拖動(dòng)事件
 domdrugstart(sort, code, ee) {
  ee.dataTransfer.setData("code", code);
  ee.dataTransfer.setData("sort", sort);
 }
 // 拖動(dòng)后鼠標(biāo)進(jìn)入另一個(gè)可接受區(qū)域
 dragenter(ee) {
  ee.target.style.border = '2px dashed #008dff';
  ee.target.style.boxShadow = '0 0 8px rgba(30, 144, 255, 0.8)';
 }
 // a拖到b,離開b的時(shí)候觸發(fā)
 dragleave(ee) {
  ee.target.style.border = '1px solid grey';
  ee.target.style.boxShadow = '';
 }
 // 對(duì)象排序
 compare(key) {
  return (obj1, obj2) => {
   if (obj1[key] < obj2[key]) {
    return -1;
   } else if (obj1[key] > obj2[key]) {
    return 1;
   }
   return 0
  }
 }
 // 當(dāng)一個(gè)元素或是選中的文字被拖拽釋放到一個(gè)有效的釋放目標(biāo)位置時(shí)
 drop(dropedSort, data, sortKey, ee) {
  ee.preventDefault();
  const code = ee.dataTransfer.getData("code");
  const sort = ee.dataTransfer.getData("sort");
  if (sort < dropedSort) {
   data.map(item => {
    if (item.code === code) {
     item[sortKey] = dropedSort;
    } else if (item[sortKey] > sort && item[sortKey] < dropedSort + 1) {
     item[sortKey]--;
    }
    return item;
   });
  } else {
   data.map(item => {
    if (item.code === code) {
     item[sortKey] = dropedSort;
    } else if (item[sortKey] > dropedSort - 1 && item[sortKey] < sort) {
     item[sortKey]++;
    }
    return item;
   });
  }
  this.props.onChange(data)
 }
 allowDrop(ee) {
  ee.preventDefault();
 }

值得注意的點(diǎn)其實(shí)只有一個(gè),我控制順序的時(shí)候,并沒有使用.target.before(document.getElementById({id}))去實(shí)際操控節(jié)點(diǎn),而是在每次觸發(fā)onDrop時(shí)間的時(shí)候,處理數(shù)據(jù)的sort,并通過onChange事件暴露給父組件,將數(shù)據(jù)輸出,通過改變value值觸發(fā)虛擬dom重新去渲染,以此控制順序。

根據(jù)公司的要求,在此基礎(chǔ)上,我還實(shí)現(xiàn)了拖拽復(fù)制的功能,這個(gè)等下次自己不懶的時(shí)候再記錄下來(lái)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • React Fiber結(jié)構(gòu)的創(chuàng)建步驟

    React Fiber結(jié)構(gòu)的創(chuàng)建步驟

    這篇文章主要介紹了React Fiber結(jié)構(gòu)的創(chuàng)建步驟,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • 通過示例講解Remix?設(shè)計(jì)哲學(xué)理念

    通過示例講解Remix?設(shè)計(jì)哲學(xué)理念

    這篇文章主要為大家通過示例講解了Remix?設(shè)計(jì)哲學(xué)理念,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • React如何使用錯(cuò)誤邊界(Error Boundaries)捕獲組件錯(cuò)誤

    React如何使用錯(cuò)誤邊界(Error Boundaries)捕獲組件錯(cuò)誤

    在 React 里,錯(cuò)誤邊界就像是一個(gè)“小衛(wèi)士”,專門負(fù)責(zé)在組件出現(xiàn)錯(cuò)誤時(shí)挺身而出,避免整個(gè)應(yīng)用因?yàn)橐粋€(gè)小錯(cuò)誤就崩潰掉,下面小編就來(lái)為大家介紹一下如何利用它捕獲組件錯(cuò)誤吧
    2025-03-03
  • Hello?React的組件化方式之React入門小案例演示

    Hello?React的組件化方式之React入門小案例演示

    這篇文章主要介紹了Hello?React的組件化方式-React入門小案例,本文通過Hello?React的案例,?來(lái)體驗(yàn)一下React開發(fā)模式,?以及jsx的語(yǔ)法,需要的朋友可以參考下
    2022-10-10
  • React Native 混合開發(fā)多入口加載方式詳解

    React Native 混合開發(fā)多入口加載方式詳解

    這篇文章主要介紹了React Native 混合開發(fā)多入口加載方式詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • React的三大屬性你都知道嗎

    React的三大屬性你都知道嗎

    這篇文章主要為大家詳細(xì)介紹了React的三大屬性,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • redux的原理、工作流程及其應(yīng)用方式

    redux的原理、工作流程及其應(yīng)用方式

    這篇文章主要介紹了redux的原理、工作流程及其應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • React中多語(yǔ)言的配置方式

    React中多語(yǔ)言的配置方式

    這篇文章主要介紹了React中多語(yǔ)言的配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • React Native自定義Android的SSL證書鏈校驗(yàn)

    React Native自定義Android的SSL證書鏈校驗(yàn)

    這篇文章主要為大家介紹了React Native自定義Android的SSL證書鏈校驗(yàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • React中父組件如何獲取子組件的值或方法

    React中父組件如何獲取子組件的值或方法

    這篇文章主要介紹了React中父組件如何獲取子組件的值或方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08

最新評(píng)論

军事| 广德县| 锦屏县| 霍邱县| 广宁县| 长葛市| 都安| 和田市| 山西省| 法库县| 留坝县| 米林县| 盱眙县| 定安县| 藁城市| 林芝县| 会宁县| 垫江县| 梅河口市| 右玉县| 黄大仙区| 鄂托克旗| 上犹县| 金昌市| 兴仁县| 托克逊县| 礼泉县| 安乡县| 墨玉县| 米脂县| 普兰店市| 都兰县| 沾益县| 武宣县| 江安县| 来宾市| 汾阳市| 隆回县| 龙南县| 乌兰县| 文化|