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

相关推荐
GISer_Jing6 分钟前
前端面试常考题目详解
前端·javascript
Boilermaker19921 小时前
【Java EE】SpringIoC
前端·数据库·spring
中微子1 小时前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y2 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁2 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry2 小时前
Fetch 笔记
前端·javascript
拾光拾趣录2 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟2 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan2 小时前
一文了解什么是Dart
前端·flutter·dart