组件文档 https://github.com/clauderic/react-sortable-hoc
在线demo https://clauderic.github.io/react-sortable-hoc/
image.png

  1. npm install react-sortable-hoc --save

List拖拽

使用 distance prop设置触发排序之前要拖动的最小距离

  • 例如设置10px的距离,distance={10}
  • 这时直接点击就不会立即触发 SortableContainer上的点击事件

拖拽时可能会造成样式丢失,原因是你的样式可能存在父级

  • 拖拽时 react-sorttable-hoc 会帮我们复制一份拖拽的dom节点,放到body下,
  • 所以有父级样式就访问不到了。可以把样式直接写在body,注意class命名,别和其他冲突了

image.png

  1. import React, { useEffect, useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { List, Switch, InputNumber } from 'antd';
  4. import {
  5. SortableContainer, SortableElement,
  6. } from 'react-sortable-hoc';
  7. import { arrayMove } from '@utils/array';
  8. const itemStyle = { padding: '8px 15px', zIndex: 1000 };
  9. const SortableItem = SortableElement(({ value }) => {
  10. return (
  11. <List.Item
  12. style={itemStyle}
  13. actions={[
  14. <InputNumber
  15. min={0}
  16. max={100}
  17. size='small'
  18. defaultValue={value.sort}
  19. />,
  20. <Switch checked={value.checked} />,
  21. ]}>
  22. {value.title}
  23. </List.Item>
  24. );
  25. });
  26. const SortableList = SortableContainer(({ value }) => (
  27. <List
  28. dataSource={value}
  29. renderItem={(item, index) =>
  30. <SortableItem key={index} index={index} value={item} />}
  31. />
  32. ));
  33. SortList.propTypes = {
  34. value: PropTypes.array.isRequired,
  35. onChange: PropTypes.func.isRequired,
  36. };
  37. function SortList({ value, onChange }) {
  38. const [data, setList] = useState(value);
  39. useEffect(() => {
  40. setList(value);
  41. }, [value]);
  42. function onSortEnd({ oldIndex, newIndex }) {
  43. if (oldIndex === newIndex) return;
  44. const arr = arrayMove(data, oldIndex, newIndex);
  45. setList(arr);
  46. onChange(arr);
  47. };
  48. return (
  49. <SortableList
  50. value={data}
  51. onSortEnd={onSortEnd}
  52. distance={10}
  53. />
  54. );
  55. }
  56. export default SortList;

九宫格拖拽

pressDelay设置低于300ms时,造成的问题:点击按钮click没有效果,解决:

pointer-events 阻止hover、active、onclick等触发事件来
https://www.imooc.com/article/48022
http://clauderic.github.io/react-sortable-hoc/#/basic-configuration/grid?_k=vq2z4r
image.png

Card卡片拖拽

https://css-tricks.com/draggin-and-droppin-in-react/
https://segmentfault.com/a/1190000020151524
image.png

card/index.js

image.png

  1. import React, { useState } from 'react';
  2. import styled from './index.module.less';
  3. import {arrayMove} from '@utils/func'
  4. import GifHoc from './GifHoc';
  5. const array = [
  6. 'https://media.giphy.com/media/3ohhwoWSCtJzznXbuo/giphy.gif',
  7. 'https://media.giphy.com/media/l46CbZ7KWEhN1oci4/giphy.gif',
  8. 'https://media.giphy.com/media/3ohzgD1wRxpvpkDCSI/giphy.gif',
  9. 'https://media.giphy.com/media/xT1XGYy9NPhWRPp4pq/giphy.gif',
  10. ]
  11. function Index() {
  12. const [gifs, setGifs] = useState(array);
  13. const [newGifs, setNewGifs] = useState([
  14. 'https://media.giphy.com/media/xiOgHgY2ceKhm46cAj/giphy.gif',
  15. 'https://media.giphy.com/media/3oKIPuMqYfRsyJTWfu/giphy.gif',
  16. 'https://media.giphy.com/media/4ZgLPakqTajjVFOVqw/giphy.gif',
  17. 'https://media.giphy.com/media/3o7btXIelzs8nBnznG/giphy.gif',
  18. ]);
  19. // 每次拖动或排序项目时触发
  20. function onSortEnd(item, e) {
  21. const { oldIndex, newIndex, collection } = item;
  22. console.log('onSortEnd', item, collection)
  23. if(collection === 'gifs') {
  24. return setGifs(arrayMove(gifs, oldIndex, newIndex));
  25. }
  26. setNewGifs(arrayMove(newGifs, oldIndex, newIndex));
  27. }
  28. return (
  29. <div className={styled.card}>
  30. <h1 className={styled.h1}>Drag those GIFs around</h1>
  31. <h2 className={styled.h2}>Set 1</h2>
  32. <GifHoc
  33. dataSource={gifs}
  34. collection="gifs"
  35. onSortEnd={onSortEnd}
  36. />
  37. <h2 className={styled.h2}>Set 2</h2>
  38. <GifHoc
  39. dataSource={newGifs}
  40. collection="newGifs"
  41. onSortEnd={onSortEnd}
  42. />
  43. </div>
  44. );
  45. }
  46. export default Index;

index.module.less

  1. .card {
  2. background: #1a1919;
  3. color: #fff;
  4. min-height: 100vh;
  5. padding: 25px;
  6. text-align: center;
  7. .h1 {
  8. font-size: 52px;
  9. margin: 0;
  10. }
  11. .h2 {
  12. color: #f6c945;
  13. text-transform: uppercase;
  14. }
  15. .img {
  16. cursor: grab;
  17. height: 180px;
  18. width: 240px;
  19. }
  20. }

SortableContainer

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { sortableContainer, sortableElement } from 'react-sortable-hoc';
  4. import styled from './index.module.less';
  5. import Gif from './Gif'
  6. // sortableContainer 所有可排序元素的容器
  7. const SortableGifsContainer = sortableContainer(({ children }) => <div className="gifs">{children}</div>);
  8. // sortableElement 每个拖拽元素的容器
  9. const SortableGif = sortableElement(({ gif, index }) =>
  10. <Gif gif={gif} key={index} />);
  11. GifHoc.propTypes = {
  12. dataSource: PropTypes.array.isRequired,
  13. };
  14. function GifHoc({ dataSource, collection, onSortEnd }) {
  15. return (
  16. <SortableGifsContainer
  17. axis="x" // x 轴拖拽
  18. onSortEnd={onSortEnd}
  19. >
  20. {dataSource.map((gif, i) =>
  21. <SortableGif
  22. // don't forget to pass index prop with item index
  23. index={i}
  24. key={gif}
  25. gif={gif}
  26. collection={collection} // 属于哪个集合
  27. />
  28. )}
  29. </SortableGifsContainer>
  30. );
  31. }
  32. export default GifHoc;

SortableItem

  1. import React from 'react';
  2. import {string} from 'prop-types';
  3. import styled from './index.module.less';
  4. Gif.propTypes = {
  5. gif: string.isRequired,
  6. };
  7. function Gif({ gif }) {
  8. return (<img src={gif} alt="gif" className={styled.img}/>);
  9. }
  10. export default Gif;

菜单拖拽排序

https://www.cnblogs.com/taohuaya/p/12753946.html