uniapp编译微信小程序拖动排序

本文若对你有用,给个免费 Star 和关注,持续输出前端各种稀奇古怪的问题

所实现的效果如图

拖动.gif

代码如下,注释齐全

  • 本段代码用到scss
<template>
  <!-- 拖动 -->
  <view class="edit-box" :style="{top:`100px`}">
    <view class='zhuti'>
      <scroll-view :scroll-y='pageInfo.scrollY' class='product-section'>
        <block v-for="(item,index) in optionLists" :key="index">
          <!-- 此处 :key='index' 不能改,只支持拖动排序,不支持修改 -->
          <view class='row list-row' :class='{"ready-place":pageInfo.readyPlaceIndex === index}'
            :style='"height: "+pageInfo.rowHeight+"px;"'>
            <view class='col1 content'>
              <text>{{item.name}}</text>
            </view>
            <view class="col3">
              <text class="iconfont icon-tuodong" 
                :data-index='index' @touchstart='dragStart'
                @touchmove='dragMove' @touchend='dragEnd'
              ></text>
            </view>
          </view>
        </block>
      </scroll-view>
      <movable-area class="movable-area"
        :style='"display:"+movableViewInfo.showClass+"; height:"+pageInfo.scrollHeight+"%"'>
        <movable-view class='row list-row movable-row' :out-of-bounds='true' damping='999'
          :style='"height:"+pageInfo.rowHeight+"px;"' direction="vertical" :y="movableViewInfo.y"
        >
          <view class='col1 content'>{{movableViewInfo.data}}</view>
          <view class="col3">
            <text class="iconfont icon-tuodong"></text>
          </view>
        </movable-view>
      </movable-area>
    </view>
  </view>
</template>

<script>
  export default {
    name: 'dragEdit',
    data() {
        return {
        // 拖动框内数据,配置
        movableViewInfo: {
          y: 0,
          showClass: 'none',  
          data: {}
        },
        optionLists: [
          { name: '苹果', code:'apple' },
          { name: '橘子', code:'orange' },
          { name: '香蕉', code:'banana' },
          { name: '油桃', code:'nectarine' },
          { name: '桃子', code:'peach' },
          { name: '蟠桃', code:'peento' },
          { name: '葡萄', code:'grape' },
          { name: '椰子', code:'coco' },
          { name: '草莓', code:'strawberry' },
          { name: '牛油果', code:'avocado' },
          { name: '枇杷', code:'loquat' },
          { name: '梨', code:'pear' },
          { name: '杏子', code:'apricot' },
          { name: '樱桃', code:'cherry' },
          { name: '甜瓜', code:'cantaloupe' },
          { name: '西瓜', code:'watermelon' },
          { name: '蓝莓', code:'blueberry' },
          { name: '猕猴桃', code:'kiwifruit' },
          { name: '菠萝', code:'pineapple' },
          { name: '柿子', code:'persimmon' },
          { name: '无花果', code:'fig' },
        ],
        pageInfo: {
          scrollY: true,        // 当为true时拖动单条,整个大盒子不会滚动
          rowHeight: 37,      // 单条行高
          scrollHeight: 100,      // 拖动时行高,百分比
          startIndex: null,     // 当前拖动第几条
          startY: 0,            // 定位拖动时的位置,需要减去上方空白部分
          readyPlaceIndex: null,    // 拖动预放置位置,拖动时有阴影的部分
          selectedIndex: null,  // 放置的位置
        }
      }
    },
    methods:{
      // 拖拽开始(按下)
      dragStart(event) {
        var startIndex = event.currentTarget.dataset.index
        // 初始化页面数据
        var pageInfo = this.pageInfo
        // 减去距离页面顶部的距离
        pageInfo.startY = event.touches[0].clientY-162
        pageInfo.readyPlaceIndex = startIndex
        pageInfo.selectedIndex = startIndex
        pageInfo.scrollY = false
        pageInfo.startIndex = startIndex
        
        // console.log('startIndex', pageInfo.readyPlaceIndex)
        this.movableViewInfo.y = pageInfo.startY - (pageInfo.rowHeight / 2)
        // 初始化拖动控件数据
        var movableViewInfo = this.movableViewInfo
        movableViewInfo.data = this.optionLists[startIndex].name
        movableViewInfo.showClass = "inline"
      
      
        this.movableViewInfo = movableViewInfo,
        this.pageInfo = pageInfo
      },
      // 拖拽移动(按住不松)
      dragMove(event) {
        var optionLists = this.optionLists
        var pageInfo = this.pageInfo
        // 计算拖拽距离
        var movableViewInfo = this.movableViewInfo
        var movedDistance = event.touches[0].clientY-162 - pageInfo.startY
        movableViewInfo.y = pageInfo.startY - (pageInfo.rowHeight / 2) + movedDistance
        // console.log('移动的距离为', movedDistance, movableViewInfo.y)
      
        // 修改预计放置位置
        var movedIndex = parseInt(movedDistance / pageInfo.rowHeight)
        var readyPlaceIndex = pageInfo.startIndex + movedIndex
        if (readyPlaceIndex < 0) {
          readyPlaceIndex = 0
        } else if (readyPlaceIndex >= optionLists.length) {
          readyPlaceIndex = optionLists.length - 1
        }
      
        if (readyPlaceIndex != pageInfo.selectedIndex) {
          var selectedData = optionLists[pageInfo.selectedIndex]
      
          optionLists.splice(pageInfo.selectedIndex, 1)
          optionLists.splice(readyPlaceIndex, 0, selectedData)
          // console.log('======optionLists', optionLists)
          pageInfo.selectedIndex = readyPlaceIndex
        }
        // 移动movableView
        pageInfo.readyPlaceIndex = readyPlaceIndex
        // console.log('移动到了索引', readyPlaceIndex, '选项为', optionLists[readyPlaceIndex])
      
      
        this.movableViewInfo = movableViewInfo
        this.optionLists = optionLists
        this.pageInfo = pageInfo
      },
      // 拖拽结束(松手)
      dragEnd(event) {
        /**
         * this.optionLists 在 dragMove 函数已经出现,
         * 但是在 dragMove 函数会多次触发,
         * 发送数据,及观察数据,在此处即可
         */
        let arr = []
        this.optionLists.forEach(item=>{
          arr.push(item.name)
        })
        console.log('optionLists',arr)
        
        // 重置页面数据
        var pageInfo = this.pageInfo
        // console.log('=====this.pageInfo before', this.pageInfo)
        // console.log('event', event)
        pageInfo.readyPlaceIndex = null
        pageInfo.startY = null
        pageInfo.selectedIndex = null
        pageInfo.startIndex = null
        pageInfo.scrollY = true
        // 隐藏movableView
        var movableViewInfo = this.movableViewInfo
        movableViewInfo.showClass = 'none'
        this.movableViewInfo = movableViewInfo
        this.pageInfo = pageInfo
        // console.log('=====this.movableViewInfo', this.movableViewInfo)
        // console.log('=====this.pageInfo', this.pageInfo)
      },
    },
  }
</script>

<style lang="scss" scoped>
  @import '/static/css/iconfont.css';
  /* 模块编辑 */
  .edit-box { width: 100%; position: absolute;
    bottom: 0; left: 0; overflow: hidden; margin-bottom: 20rpx;
  }
  .marginL6 { margin-left: 12rpx; }
  .product-section { height:100%; }
  .zhuti { width: 100%; position: absolute; top: 52px;
    bottom: 0; left: 0; overflow: scroll; }
  .row { height: 47px; width: 100%; display: flex; justify-content: space-between; align-items: center; }
  .title-row { border-bottom: 1px solid #888888; color: #888888; }
  .list-row { padding: 4px 24rpx; background-color: white; box-sizing: border-box;}
  .movable-area { position: absolute; top: 0; left: 0; z-index: 10; width: 100%; }
  .movable-row { box-shadow: #D9D9D9 0 0 20px; }
  .col1 { width: 90%; }
  .col3 { width: 6%; color: #3C63EB; }
  .ready-place { background: rgba(238, 240, 254, 0.6); }
  .content { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border: 1rpx solid #3C63EB; color:#3C63EB; box-sizing: border-box; height: 58rpx; padding: 8rpx 0 8rpx 32rpx; border-radius: 4rpx; }
</style>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容