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 自定义实现拖拽功能。这会稍微复杂一些,但能提供更高的灵活性和性能。

相关推荐
子春一212 分钟前
Flutter 2025 可访问性(Accessibility)工程体系:从合规达标到包容设计,打造人人可用的数字产品
前端·javascript·flutter
白兰地空瓶18 分钟前
别再只会调 API 了!LangChain.js 才是前端 AI 工程化的真正起点
前端·langchain
jlspcsdn1 小时前
20251222项目练习
前端·javascript·html
行走的陀螺仪2 小时前
Sass 详细指南
前端·css·rust·sass
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ2 小时前
React 怎么区分导入的是组件还是函数,或者是对象
前端·react.js·前端框架
LYFlied2 小时前
【每日算法】LeetCode 136. 只出现一次的数字
前端·算法·leetcode·面试·职场和发展
子春一22 小时前
Flutter 2025 国际化与本地化工程体系:从多语言支持到文化适配,打造真正全球化的应用
前端·flutter
QT 小鲜肉2 小时前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记
羽沢313 小时前
ECharts 学习
前端·学习·echarts