小程序自定义拖动排序(uniapp)

在这里插入图片描述

1.用到的组件和事件
1)组件movable-area,movable-view
2) @touchend(拖动离开事件),movable-view的onChange事件,自定义克隆事件dragChange,自定义顶置事件overheadChange
注意:给每个盒子设定固定高度

过程:
点击拖动:设置可移动区域,循环数组,movable-view写要移动的盒子(用点击事件点击要移动的数据进行克隆,把数据从当前数组中摘取出来放入movable-view进行移动),再利用onChange事件捕捉x,y轴,利用设置的盒子高度和当前获取的y轴数据判断当前数组的下标。当手指离开触发拖动离开事件(把克隆数据插入数组的下标位置(onchange事件获取的下标)。
顶置:用splice方法返回删除的数组中的某一数据,再用unshift方法放到数组第一位。

可用参数

 kelongList = {};
  classClass = 0;
  sortList: Array<any> = [
    {
      labelLevel: 0,
      labelId: 0,
      tagName: "关于我的",
      campusShootingLabelType: 0,
      createUserType: 0,
    },
    {
      labelLevel: 0,
      labelId: 0,
      tagName: "我发布的",
      campusShootingLabelType: 0,
      createUserType: 0,
    },
  ];

  x = 0;
  y = 0;
  old = {
    x: 0,
    y: 0,
  };
  pagesX = 0;
  pagesY = 0;
  moveIndex = -1;
  monitor = 0; //初始值0:监听拖动的盒子可出现  1:显示拖动的盒子  2:不显示拖动的盒子
  kelongIndex = -1; //初始值 代表没有被移动的标签

1.movable-area指代可拖动的范围,在其中内嵌movable-view组件用于指示可拖动的区域。

 <movable-area>
      <view class="container">
        <view class="" v-for="(item, index) in sortList" :key="index">
          <!-- <view class="move_null" v-show="index == moveIndex"> </view> -->

          <view class="flex justify-between conBox padding-lg">
            <view class="title">{{ item.tagName }}</view>
            <view class="flex">
              <view class="Over" @click="overheadChange($event, index, item)">
                <text
                  v-if="index == 0"
                  class="lg text-orange cuIcon-check"
                ></text>
                <image
                  v-else
                  src="/pagesTaskLeave/static/overhead.png"
                  style="weight: 48rpx; height: 48rpx"
                ></image>
              </view>
              <view class="sort" @click="dragChange($event, index, item)"
                ><image
                  src="/pagesTaskLeave/static/antOutline.png"
                  style=""
                ></image
              ></view>
            </view>
          </view>
        </view>
        <view class="list_bottom"> </view>
      </view>

      <movable-view
        :x="x"
        :y="pagesY"
        direction="vertical"
        v-show="pagesX != 0 && pagesY != 0 && monitor == 1"
        @change="onChange"
      >
        <view class="bg-green flex justify-between moveBox" @touchend="tap">
          <view>{{ kelongList[0].tagName }}</view>
          <view style="margin-left: 186rpx">
            <image
              src="/pagesTaskLeave/static/overhead.png"
              style="width: 48rpx; height: 48rpx"
            ></image
          ></view>
          <view style="margin-right: 14rpx"
            ><image
              src="/pagesTaskLeave/static/antOutline.png"
              style="width: 48rpx; height: 48rpx"
            ></image
          ></view>
        </view>
      </movable-view>
    </movable-area>

2.点击进行克隆,并且数据放入movable-view就能移动

 // 克隆
  dragChange(e: any, index: any, item: any) {
    //如果有克隆下标,说明上一个移动还没结束,不对其他标签有克隆的点击事件
    console.log(index);
    if (this.kelongIndex != -1) {
      return;
    } else {
      console.log("kelongIndex:" + this.kelongList);
    }
    this.kelongIndex = index;
    this.monitor = 1;
    this.pagesX = e.detail.x;
    this.pagesY = e.detail.y - 120;
    console.log(e.detail.y);
    console.log(this.pagesY);
    // this.pagesY = parseInt(e.detail.y) - 140;
    var list = this.sortList.splice(index, 1);
    this.kelongList = list;
  }

3.onChange事件捕捉x,y轴,获取移动的下标

onChange(e: any) {
    this.old.x = e.detail.x;
    this.old.y = e.detail.y;

    for (var i = 0; i < 40; i++) {
      var start = i * 35;
      var end = (i + 1) * 35;
      if (this.old.y >= start && this.old.y < end) {
        this.moveIndex = i;
        break;
      }
    }
  }

4.手指离开触发拖动离开事件(把克隆数据插入数组的下标位置(onchange事件获取的下标)。

 //拖动离开事件
  tap(e: any) {
    console.log("移动下标" + this.moveIndex);
    if (this.moveIndex != -1) {
      var list: any = this.kelongList;
      this.sortList.splice(this.moveIndex, 0, list[0]);
      this.kelongList = {};
      this.monitor = 2;
      //确保不出现空
      for (let i = 0; i < this.sortList.length; i++) {
        if (this.sortList[i] == null || this.sortList[i] == undefined) {
          this.sortList.splice(i, 1);
          continue;
        }
      }
      var a = uni.setStorageSync("sort", this.sortList);
      this.moveIndex = -1;
      this.kelongIndex = -1;
    } else {
      var list: any = this.kelongList;
      this.sortList.splice(this.kelongIndex, 0, list[0]);
      this.kelongList = {};
      this.moveIndex = -1;
      this.monitor = 2;
      this.kelongIndex = -1;
    }
  }

顶置

//顶置
  overheadChange(e: any, index: any, item: any) {
    this.classClass = 1;
    var list = this.sortList.splice(index, 1);

    this.sortList.unshift(list[0]);

    var a = uni.setStorageSync("sort", this.sortList);
  }

全部代码

<template>
  <view>
    <!-- 顶部导航 -->
    <view>
      <cu-custom bgColor="bg-greenac70" isBack="true">
        <block slot="backText"></block>
        <block slot="content">分类管理</block>
      </cu-custom>
    </view>
    <view>
      <view class="flex justify-between padding-lg topBox">
        <view>分类名称</view>
        <view class="flex">
          <view class="Overhead">顶置</view>
          <view>拖动排序</view>
        </view>
      </view>
    </view>
    <movable-area>
      <view class="container">
        <view class="" v-for="(item, index) in sortList" :key="index">
          <!-- <view class="move_null" v-show="index == moveIndex"> </view> -->

          <view class="flex justify-between conBox padding-lg">
            <view class="title">{{ item.tagName }}</view>
            <view class="flex">
              <view class="Over" @click="overheadChange($event, index, item)">
                <text
                  v-if="index == 0"
                  class="lg text-orange cuIcon-check"
                ></text>
                <image
                  v-else
                  src="/pagesTaskLeave/static/overhead.png"
                  style="weight: 48rpx; height: 48rpx"
                ></image>
              </view>
              <view class="sort" @click="dragChange($event, index, item)"
                ><image
                  src="/pagesTaskLeave/static/antOutline.png"
                  style=""
                ></image
              ></view>
            </view>
          </view>
        </view>
        <view class="list_bottom"> </view>
      </view>

      <movable-view
        :x="x"
        :y="pagesY"
        direction="vertical"
        v-show="pagesX != 0 && pagesY != 0 && monitor == 1"
        @change="onChange"
      >
        <view class="bg-green flex justify-between moveBox" @touchend="tap">
          <view>{{ kelongList[0].tagName }}</view>
          <view style="margin-left: 186rpx">
            <image
              src="/pagesTaskLeave/static/overhead.png"
              style="width: 48rpx; height: 48rpx"
            ></image
          ></view>
          <view style="margin-right: 14rpx"
            ><image
              src="/pagesTaskLeave/static/antOutline.png"
              style="width: 48rpx; height: 48rpx"
            ></image
          ></view>
        </view>
      </movable-view>
    </movable-area>
  </view>
</template>

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import RequestPageBase from "@/lib/request-page-base";
// import func from "vue-temp/vue-editor-bridge";
import { filter } from "vue/types/umd";
import Splash from "@/pages/splash/index.vue";

@Component({})
export default class 文件名称 extends RequestPageBase {
  kelongList = {};
  classClass = 0;
  sortList: Array<any> = [
    {
      labelLevel: 0,
      labelId: 0,
      tagName: "关于我的",
      campusShootingLabelType: 0,
      createUserType: 0,
    },
    {
      labelLevel: 0,
      labelId: 0,
      tagName: "我发布的",
      campusShootingLabelType: 0,
      createUserType: 0,
    },
  ];

  x = 0;
  y = 0;
  old = {
    x: 0,
    y: 0,
  };
  pagesX = 0;
  pagesY = 0;
  moveIndex = -1;
  monitor = 0; //初始值0:监听拖动的盒子可出现  1:显示拖动的盒子  2:不显示拖动的盒子
  kelongIndex = -1; //初始值 代表没有被移动的标签
  onLoad() {
    this.sortList = uni.getStorageSync("sort");
  }

  //拖动离开事件
  tap(e: any) {
    console.log("移动下标" + this.moveIndex);
    if (this.moveIndex != -1) {
      var list: any = this.kelongList;
      this.sortList.splice(this.moveIndex, 0, list[0]);
      this.kelongList = {};
      this.monitor = 2;
      //确保不出现空
      for (let i = 0; i < this.sortList.length; i++) {
        if (this.sortList[i] == null || this.sortList[i] == undefined) {
          this.sortList.splice(i, 1);
          continue;
        }
      }
      var a = uni.setStorageSync("sort", this.sortList);
      this.moveIndex = -1;
      this.kelongIndex = -1;
    } else {
      var list: any = this.kelongList;
      this.sortList.splice(this.kelongIndex, 0, list[0]);
      this.kelongList = {};
      this.moveIndex = -1;
      this.monitor = 2;
      this.kelongIndex = -1;
    }
  }
  // 克隆
  dragChange(e: any, index: any, item: any) {
    //如果有克隆下标,说明上一个移动还没结束,不对其他标签有克隆的点击事件
    console.log(index);
    if (this.kelongIndex != -1) {
      return;
    } else {
      console.log("kelongIndex:" + this.kelongList);
    }
    this.kelongIndex = index;
    this.monitor = 1;
    this.pagesX = e.detail.x;
    this.pagesY = e.detail.y - 120;
    console.log(e.detail.y);
    console.log(this.pagesY);
    // this.pagesY = parseInt(e.detail.y) - 140;
    var list = this.sortList.splice(index, 1);
    this.kelongList = list;
  }
  //顶置
  overheadChange(e: any, index: any, item: any) {
    this.classClass = 1;
    var list = this.sortList.splice(index, 1);

    this.sortList.unshift(list[0]);

    var a = uni.setStorageSync("sort", this.sortList);
  }

  onChange(e: any) {
    this.old.x = e.detail.x;
    this.old.y = e.detail.y;

    for (var i = 0; i < 40; i++) {
      var start = i * 35;
      var end = (i + 1) * 35;
      if (this.old.y >= start && this.old.y < end) {
        this.moveIndex = i;
        break;
      }
    }
  }
}
</script>

<style lang="less" scoped>
.move_null {
  width: 100%;
  height: 80rpx;
  // background-color: aqua;
}
.list_bottom {
  background-color: #f7f3f3;
  width: 100%;
  height: 80rpx;
}
movable-area {
  movable-view {
    width: 100%;
  }
  width: 100%;
  height: 100%;
  .moveBox {
    height: 80rpx;
    padding: 20rpx 30rpx 0 30rpx;
  }
}
.topBox {
  font-size: 28rpx;
  text-align: left;
  .Overhead {
    margin-right: 100rpx;
  }
}
.container {
  background-color: white;
  .conBox {
    align-items: center;
    height: 80rpx;
    font-size: 28rpx;
    text-align: left;
    border-bottom: 1px solid rgb(244, 242, 242);

    .Over {
      margin-right: 150rpx;
      width: 48rpx;
      height: 48rpx;
      font-size: 48rpx;
    }
    .sort {
      margin-right: 20rpx;
      width: 48rpx;
      height: 48rpx;
      image {
        width: 48rpx;
        height: 48rpx;
      }
    }
  }
}
</style>
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值