账户中心 退出系统
5.0 版本 3.0 版本
使用手册 模板中心 账户中心 合作 · 服务
快速开始
框架介绍版权要求
更新日志
常见问题
框架部署目录结构
版本差别V5 vs V3
皮肤说明
nvue 说明
数据转换格式问题
页面布局 ( 15 )
页面组件 独创 · 好用
全屏加载 + 挂件
自定义头部返回 · 主页
自定义头部动态变化
自定义头部双击回顶部
返回顶部页面模式
返回顶部内置滚动区域模式
自定义底部详情模式
自定义 tabbar凸出按钮
吸顶元素插槽实现
动态吸顶逻辑演示
吸顶 + 滚动主体布局演示
iPhone 底部适配自动适配
小程序胶囊按钮躲避
下拉选择筛选 · 排序
框架基础 ( 8 )
文本相关尺寸及修饰
内置颜色colors.css
定位样式absolute · fixed
手势操作触屏 · 缩放
内置图标
按钮样式
常用标题更多 · 换一批
动画效果
Grace.JS ( 16 )
工具介绍
网络请求
页面跳转
数据缓存
图片操作
设备信息
消息提示
头部导航 动态设置
底部导航 动态设置
元素选择 尺寸获取
字符常用
数组操作
随机数据
日期时间
延时循环
对象操作
请求工具库 ( 8 )
工具库介绍
GET 请求
POST 请求
upload 上传
签名验证 对 键 进行签名
签名验证 对 值 进行签名
用户登录检查
后端代码 php 版本示例
常用组件 ( 18 )
图片组件等比缩放
排序按钮
搜索组件
徽章角标
标签组件
功能标签选择 · 删除
星级组件
倒计时组件
城市选择
地区联动省市区三级
链接组件
为空展示
多图选择
多图上传
头像群组
数值动画
PK 投票
抽奖转盘
常用布局 ( 10 )
Flex布局必备技能
宫格布局默认5格
普通表格
数据表格
横向公告
时间轴布局
步骤展示
骨架加载
瀑布流布局
启动页广告全屏轮播形式
列表布局 ( 8 )
列表布局样式模式
滑动列表
可选列表
全选列表
树状列表
排序列表竖向拖拽
卡片列表
名片卡片
切换布局 ( 8 )
切换导航单行
切换导航多行
局部选项卡
全屏选项卡布局原理
分段切换
折叠面板
竖向切换导航适配
分类切换
滚动 · 轮播 ( 8 )
滚动区域原生 scroll-view
横向滚动带有进度条
滚动公告基于 swiper
无缝滚动横向文本形式
无缝滚动横向卡片形式
竖向公告顺序卡片形式
轮播组件
主体滚动定位+滚动区域
刷新加载 ( 6 )
全屏加载遮罩模式
下拉刷新基于页面组件
加载更多基于页面组件
刷新和加载基于页面组件
刷新和加载自定义组合
刷新和加载原生组合模式
弹层 · 对话框 ( 6 )
遮罩弹层 popup
顶部消息框
模态对话框
底部操作表
右侧菜单
弹出菜单 popup menu
表单相关 ( 14 )
表单元素 form 布局
提交按钮
表单验证
字数限制
动态表单 添加删除元素
分步提交
步进器
数字键盘
车牌号键盘
滑动解锁
进度滑块 单滑块
区间滑块 双滑块
功能标签 选择 · 删除
点选按钮
日期时间 ( 6 )
日历日期 带有农历及时间
日期区间 日历形式
日期时间 picker 模式
时间段选择 picker 模式
日程日历 日程 · 提醒
横向日历 布局模式
文章相关 ( 11 )
文章列表 基础用法
文章列表 切换模式
文章列表 全屏选项卡模式
编辑器 自主研发 · 多端兼容
格式转换 后端转换为 HTML
文章详情 编辑器解析
富文本 字符串转数组
展开阅读
评论布局
评论提交
底部分享
媒体播放 ( 2 )
音乐播放器
视频播放器
地图使用 ( 3 )
位置标注
地图周边
拖拽定位
用户模板 ( 9 )
用户登录
手机号登录
短信登录
短信验证
个人中心
头像剪裁
证件上传
会员排行榜
手写签名
电商常用 ( 10 )
商品列表
商品详情
订单中心
购物车模板
排序与筛选
地址列表
地址添加
抽奖模板
分类图标
优惠券组件
即时通讯 ( 3 )
消息展示组件
消息输入组件
消息列表展示
二维码及条码 ( 3 )
二维码生成
条形码生成
海报模板
竖向拖拽排序

手册版本 V5.0

竖向拖动排序介绍

01. 封装为组件在使用时反而不灵活,所以使用页面布局实现;
02. 利用手指事件完成拖拽及拖拽完成后的数据排序功能;
03. 因 weex 底层原因暂不支持,请使用 vue 页面完成此功能;

核心事件

01. onLoad : 模拟 api 请求,并补全数据属性
02. longtap : 长按后才能进行拖拽
03. thStart : 手指滑动开始
04. thMove : 手指滑动
05. thEnd : 拖拽完成对数据进行重新排序

兼容平台

H5APP小程序NVUE
×

演示代码

<template>
	<view>
		<view class="gui-margin" style="padding-top:50rpx;">
			<text class="gui-h5 gui-bold gui-color-gray">效果演示</text>
		</view>
		<view class="drag-list gui-margin-top" @touchmove.stop.prevent="thMoveS">
			<view v-for="(item, index) in lists" :key="index" 
			:style="{
			transform:'translateY('+lists[index].y+'px) translateZ('+(index == movingIndex ? '120px' : '0px' )+')',
			position:lists[index].y != 0 ? 'absolute' : 'relative', 
			paddingTop:index==preIndex?'20px':'0', 
			opacity:index == movingIndex ? 0.9 : 1,
			background:index == movingIndex?'rgba(0,0,0,0.1)':'#FFFFFF'}" 
			@touchstart="thStart" @touchmove="thMove" @touchend="thEnd" 
			class="drag-list-item" @longpress="longtap" :data-index="index" :id="'draglist'+index">
				<view class="drag-list-order">{{index + 1}}</view>
				<image :src="item.img" class="drag-list-img" mode="widthFix"></image>
				<view class="drag-list-content">{{item.title}}</view>
				<view class="drag-list-icon gui-icons" :style="{color:index==movingIndex ? '#3688FF' : '#A5A7B2'}">&#xe727;</view>
			</view>
		</view>
	</view>
</template>
<script>
var graceJS = require('@/GraceUI5/js/grace.js');
var demoData = [
	{img:'http://img4.imgtn.bdimg.com/it/u=552119130,3001255642&fm=26&gp=0.jpg',title:"小明 0"},
	{img:'http://img2.imgtn.bdimg.com/it/u=3428383444,2828052422&fm=26&gp=0.jpg', title:"小米 1"},
	{img:'http://img2.imgtn.bdimg.com/it/u=1972994033,181763631&fm=26&gp=0.jpg', title:"美美 2"},
	{img:'http://img1.imgtn.bdimg.com/it/u=291222564,3369340489&fm=26&gp=0.jpg', title:"小牛 3"},
	{img:'http://img3.imgtn.bdimg.com/it/u=3904304279,448031564&fm=26&gp=0.jpg', title:"小林 4"}
];
export default {
	data(){
		return {
			lists : [],
			movingIndex : -1,
			preIndex    : -1,
			dragTimer   : null,
			moveStartY  : 0,
			pageScrollTop   : 0,
			pageScrollTimer : null
		}
	},
	onLoad : function(){
		// 模拟 api 请求
		setTimeout(()=>{
			// api 数据内没有 y 坐标记录循环补充
			for(let i = 0; i < demoData.length; i++){
				demoData[i].y = 0;
				demoData.splice(i,1,demoData[i]);
			}
			this.lists = demoData;
		});
	},
	onPageScroll:function(e){
		clearTimeout(this.pageScrollTimer);
		this.pageScrollTimer = setTimeout(()=>{
			this.pageScrollTop = e.scrollTop;
		}, 200);
	},
	methods:{
		// 长按后才能进行拖拽
		longtap:function(e){
			this.movingIndex = Number(e.currentTarget.dataset.index);
			this.preIndex = -1;
		},
		thStart:function(e){
			this.moveStartY = Number(e.touches[0].pageY);
		},
		// 移动进行拖拽
		thMove : function(e){
			if(this.movingIndex == -1){return ;}
			var moveY = Number(e.touches[0].pageY) - this.moveStartY;
			if(moveY < -30 && this.preIndex < this.movingIndex){moveY -= 20;}
			this.lists[this.movingIndex].y = moveY;
			this.lists.splice(this.movingIndex, 1, this.lists[this.movingIndex]);
			this.moveBase();
		},
		thMoveS  : function (e) {
			if(this.movingIndex == -1){
				var moveY          = Number(e.touches[0].pageY) - this.moveStartY;
				moveY              *= -1;
				this.pageScrollTop = this.pageScrollTop  + moveY;
				if(this.pageScrollTop < 0){this.pageScrollTop = 0;}
				uni.pageScrollTo({
					scrollTop : this.pageScrollTop,
					duration  : 0
				});
			}
		},
		moveBase : function () {
			if(this.dragTimer != null){return ;}
			this.dragTimer = 1;
			setTimeout(()=>{this.dragTimer = null;}, 100);
			graceJS.selectAll('.drag-list-item', (resIn)=>{
				if(!resIn){return ;}
				graceJS.select('#draglist'+this.movingIndex, (res)=>{
					if(!res){return ;}
					// 上下移动
					var currentTop   = res.top;
					for(let i = 0; i < resIn.length; i++){
						if(i != this.movingIndex){
							var top = resIn[i].top;
							if(currentTop < top){
								this.preIndex = i;
								break;
							}else{
								this.preIndex = this.lists.length;
							}
						}
					}
				});
			});
		},
		// 拖拽完成 完成后 lists 数组会被重新排序
		thEnd : function (e) {
			if(this.movingIndex == -1 || this.preIndex == -1){
				this.movingIndex = -1;
				this.preIndex = -1;
				return ;
			}
			this.lists[this.movingIndex].y = 0;
			var dragData = JSON.stringify(this.lists);
			dragData     = JSON.parse(dragData);
			if(this.movingIndex > this.preIndex){
				var dropOrder = dragData.splice(this.movingIndex, 1);
				dragData.splice(this.preIndex, 0 , dropOrder[0]);
			}else{
				dragData.splice(this.preIndex, 0 , dragData[this.movingIndex]);
				dragData.splice(this.movingIndex, 1);
			}
			this.$nextTick(()=>{
				this.movingIndex = -1;
				this.$nextTick(()=>{
					this.preIndex    = -1;
					this.$nextTick(()=>{
						this.lists    = dragData;
						this.$nextTick(()=>{
							this.movingIndex = -1;
							this.preIndex = -1;
						})
					})
				});
			});
		}
	}
}
</script>
<style>
.drag-list{padding-left:25rpx; transform-style:preserve-3d; position:relative;}
.drag-list-item{display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center; background:#FFFFFF;}
.drag-list-order{width:50rpx; text-align:center; margin:0 10px; flex-shrink:0; font-size:36rpx; font-style:italic; color:#A5A7B2;}
.drag-list-icon{width:60rpx; line-height:60rpx; flex-shrink:0; font-size:36rpx; color:#A5A7B2;}
.drag-list-img{width:66rpx; height:66rpx; flex-shrink:0; font-size:36rpx; border-radius:60rpx;}
.drag-list-content{width:700rpx; line-height:120rpx; font-size:28rpx; margin-left:20rpx;}
</style>