Uniapp 和 React Native 拖拽实现

Uniapp 两个列表之间的相互拖拽

uni-app 中实现两个列表之间的相互拖拽可以利用 SortableJS 来完成。uni-app 支持使用 SortableJS 进行复杂的拖拽交互,但要确保兼容性和正确的使用方式。以下是实现两个列表互相拖拽的步骤:

1. 安装 SortableJS

首先,确保你已经安装了 SortableJS。你可以通过 npm 安装它,可以运行:

npm install sortablejs

2. 设置 HTML 结构

uni-app 页面中,定义两个列表的结构:

html 复制代码
    <template>
      <view class="container">
        <view id="list1" class="list">
          <view v-for="(item, index) in list1" :key="index" class="item">{{ item }}</view>
        </view>
        <view id="list2" class="list">
          <view v-for="(item, index) in list2" :key="index" class="item">{{ item }}</view>
        </view>
      </view>
    </template>

    <script>
    import Sortable from 'sortablejs';

    export default {
      data() {
        return {
          list1: ['Item 1', 'Item 2', 'Item 3'],
          list2: ['Item A', 'Item B', 'Item C']
        };
      },
      mounted() {
        this.initSortable();
      },
      methods: {
        initSortable() {
          const list1 = document.getElementById('list1');
          const list2 = document.getElementById('list2');
          
          Sortable.create(list1, {
            group: 'shared',
            animation: 150,
            onEnd: (evt) => this.handleEnd(evt)
          });

          Sortable.create(list2, {
            group: 'shared',
            animation: 150,
            onEnd: (evt) => this.handleEnd(evt)
          });
        },
        handleEnd(evt) {
          // evt.from - 拖拽来源
          // evt.to - 拖拽目标
          // evt.item - 被拖拽的项目
          // evt.oldIndex - 拖拽前的索引
          // evt.newIndex - 拖拽后的索引

          if (evt.from === evt.to) return; // 如果没有跨列表,不处理

          const item = evt.item.innerText; // 获取拖拽项的内容
          const fromList = evt.from.id === 'list1' ? this.list1 : this.list2;
          const toList = evt.to.id === 'list1' ? this.list1 : this.list2;

          fromList.splice(evt.oldIndex, 1); // 从原列表中移除
          toList.splice(evt.newIndex, 0, item); // 添加到目标列表
        }
      }
    };
    </script>

    <style scoped>
    .container {
      display: flex;
    }
    .list {
      width: 200px;
      min-height: 300px;
      margin: 10px;
      padding: 10px;
      border: 1px solid #ccc;
      background-color: #f9f9f9;
    }
    .item {
      padding: 8px;
      margin: 5px 0;
      background-color: #fff;
      border: 1px solid #ddd;
      cursor: move;
    }
    </style>

3. 代码解析

  • Sortable.create :初始化可拖拽的列表,并指定 group 属性为 'shared' 以允许列表间的拖拽。
  • handleEnd:处理拖拽结束事件,更新数据模型以反映拖拽操作。在此函数中,我们从源列表中移除拖拽的项,并将其添加到目标列表。

react native 两个列表相互拖拽

在 React Native 中实现两个列表之间的相互拖拽,可以利用 react-native-draggable-flatlistreact-native-reanimatedreact-native-gesture-handler 等库来实现。以下是一个使用 react-native-draggable-flatlist 的示例,演示如何实现两个列表的拖拽功能。

1. 安装依赖

首先,你需要安装 react-native-draggable-flatlist,这是一个支持拖拽排序的 FlatList 组件。你可以通过以下命令安装:

java 复制代码
npm install react-native-draggable-flatlist

2. 设置基础代码

在 React Native 项目中,创建一个组件,包含两个可以拖拽的列表。

jsx 复制代码
    import React, { useState } from 'react';
    import { View, Text, StyleSheet, Alert, Button } from 'react-native';
    import DraggableFlatList from 'react-native-draggable-flatlist';

    const App = () => {
      const [list1, setList1] = useState(['Item 1', 'Item 2', 'Item 3']);
      const [list2, setList2] = useState(['Item A', 'Item B', 'Item C']);

      const onDragEnd = (listIndex) => (info) => {
        const { data, from, to } = info;

        if (from === to) return;

        const item = data[from];
        const sourceList = listIndex === 1 ? list1 : list2;
        const targetList = listIndex === 1 ? list2 : list1;

        const updatedSourceList = sourceList.filter((_, index) => index !== from);
        const updatedTargetList = [...targetList.slice(0, to), item, ...targetList.slice(to)];

        if (listIndex === 1) {
          setList1(updatedSourceList);
          setList2(updatedTargetList);
        } else {
          setList1(updatedTargetList);
          setList2(updatedSourceList);
        }
      };

      return (
        <View style={styles.container}>
          <DraggableFlatList
            data={list1}
            renderItem={({ item, index, drag }) => (
              <View style={styles.item} onLongPress={drag}>
                <Text>{item}</Text>
              </View>
            )}
            keyExtractor={(item) => item}
            onDragEnd={onDragEnd(1)}
            style={styles.list}
          />
          <DraggableFlatList
            data={list2}
            renderItem={({ item, index, drag }) => (
              <View style={styles.item} onLongPress={drag}>
                <Text>{item}</Text>
              </View>
            )}
            keyExtractor={(item) => item}
            onDragEnd={onDragEnd(2)}
            style={styles.list}
          />
        </View>
      );
    };

    const styles = StyleSheet.create({
      container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-around',
        padding: 16,
      },
      list: {
        width: '45%',
      },
      item: {
        padding: 16,
        marginBottom: 8,
        backgroundColor: '#f9f9f9',
        borderColor: '#ddd',
        borderWidth: 1,
        borderRadius: 4,
      },
    });

    export default App;

3. 代码解析

  • DraggableFlatList:用于显示可拖拽的列表。
  • onDragEnd :处理拖拽结束后的逻辑。它接受 listIndex 来区分当前拖拽操作是哪个列表的,然后根据 info 对象中的 fromto 属性更新列表数据。

4. 使用 react-native-reanimatedreact-native-gesture-handler

如果你需要更复杂的拖拽效果,可以考虑使用 react-native-reanimatedreact-native-gesture-handler 自定义实现拖拽功能。这会稍微复杂一些,但能提供更高的灵活性和性能。

相关推荐
m0_526119401 分钟前
评论的组件封装
开发语言·前端·javascript
GISer_Jing17 分钟前
Cesium加载高速公路样式线图层和利用CSS撰写高速公路样式
前端·css·webgl
竹竹零20 分钟前
HTML第一课 语法规范与常用标签
前端·html
人间有清欢1 小时前
三、导航&事件&生命周期
前端·javascript·微信小程序
qq_274499931 小时前
typeof null返回值为什么是object?
开发语言·前端·javascript
xiaolongyu31 小时前
2 html5 浏览器已经支持的新API
前端·html·html5
_.Switch2 小时前
Node.js 数据库操作详解:构建高效的数据持久化层
运维·服务器·前端·数据库·系统架构·前端框架·node.js
I_am_shy2 小时前
js模块化 --- commonjs规范 原理详解
开发语言·前端·javascript·commonjs
.小董同学2 小时前
Vue eslint 语法检测问题
前端·javascript·vue.js
IT北辰2 小时前
用HTML写一个动态的的电子相册实战详细案例
前端·html