jwyu 3 лет назад
Родитель
Сommit
666a4c8f3c

BIN
components/.DS_Store


+ 0 - 364
components/chartList/chartList.vue

@@ -1,364 +0,0 @@
-<template>
-  <view class="chart-list-wrap">
-    <scroll-view 
-      id="scrollView" 
-      :scroll-y="true" 
-      :style="{'height': ListHeight+'px'}" 
-      :scroll-top="scrollViewTop"
-      @scrolltolower="scrolltolower"
-		  @scroll="drag.scroll" 
-      :scroll-with-animation="false"
-    >
-      <!-- 两个list列表 拖拽完直接切换list 避免闪烁 -->
-      <block v-for="(tmplist,listType) in dragList" :key="listType">
-        <view 
-          class="chart-list" 
-          :class="[listType=='A'?(listSwitch?'show':'hide'):(listSwitch?'hide':'show')]"
-        >
-          <block v-for="(item,index) in tmplist" :key="index">
-            <view class="rowBox chart-item" :id="'rowBox'+listType+index">
-            <view class="row" :id="'row'+listType+index">
-              <!-- 拖动按钮 -->
-              <image 
-                class="drag-icon" 
-                src="../../static/chart/drag-icon.png" 
-                mode="aspectFill"
-                :style="{'height': rowHeight+'px'}" 
-                :data-index="index" 
-                :data-type="listType" 
-								@touchstart="drag.touchstart" 
-                @touchmove="drag.touchmove" 
-                @touchend="drag.touchend"
-								<!-- #ifdef MP-WEIXIN -->
-								@longpress="drag.longpress"
-								<!-- #endif -->
-              />
-
-              <!-- 内容区域 -->
-              <view>标题{{item.title}}</view>
-              <image lazy-load class="img" src="" mode="aspectFill"/>
-            </view>
-            </view>
-          </block>
-        </view>
-      </block>
-    </scroll-view>
-
-    <!-- 拖动的盒子 -->
-    <view id="shadowRowBox" class="shadowRowBox">
-      <view id="shadowRow">
-        <image class="drag-icon" src="../../static/chart/drag-icon.png" mode="aspectFill"/>
-        <!-- 内容区域 -->
-        <view>标题{{shadowRow.title}}</view>
-        <image lazy-load class="img" src="" mode="aspectFill"/>
-      </view>
-    </view>
-
-
-    <view :data-isapph5="isAppH5" :data-islongtouch="isLongTouch" :data-longtouchtime="longTouchTime" :data-listheight="ListHeight"
-		 :data-rownum="list.length" id="dataView" style="display: none !important;">存放数据给wxs读取</view>
-  </view>
-</template>
-
-<script src="./drag.wxs" module="drag" lang="wxs"></script>
-<script>
-	/**  
-	 * 拖拽排序组件 HM-dragSort
-	 * @description 拖拽排序组件 HM-dragSort
-	 * @property {ObjectArray} list = [] 列表数据,自定义数据,会传递到name="rowContent"插槽  
-	 * @property {Boolean} isLongTouch = [true|false] 是否开启长按拖动  
-	 * @property {Number} longTouchTime = [] 选填,触发长按时长,单位:ms,默认350ms,不支持微信小程序 
-	 * @property {Number} listHeight = [] 选填,可拖动列表整体的高度,单位:px,默认等于窗口高度 
-	 * @property {Number} rowHeight = [] 必填,行高,单位:px,默认44px
-	 * @event {Function} change 行位置发生改变时触发事件 返回值:{index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据'}   
-	 * @event {Function} confirm 拖拽结束且行位置发生了改变触发事件 返回值:{index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据',list:'整个列表拖动后的数据'}  
-	 * @event {Function} onclick 点击行触发事件 返回值:{index:'被点击行下标',value:'被点击行数据'} 
-	 */
-	export default {
-		name: 'chart-list',
-		data() {
-			return {
-				// #ifdef APP-PLUS || H5
-				isAppH5: true,
-				// #endif
-				// #ifdef MP-WEIXIN
-				isAppH5: false,
-				// #endif
-
-				shadowRow: {}, // 存放被拖拽行数据
-				// 列表数据 分A和B两个列表 互相切换 避免闪烁
-				dragList: {
-					"A": [],
-					"B": []
-				},
-				ListHeight: this.listHeight,
-				listSwitch: true, // 控制切换列表
-
-				// 控制滑动
-				scrollViewTop: 0, // 滚动条位置
-				scrollCommand: 1, //传递renderjs数据
-				isHoldTouch: false, //是否正在拖拽
-				isScrolling: false, //是否正在滚动视图
-				scrollTimer: null, //定时器-控制滚动 微信小程序端使用 实现类似requestAnimationFrame效果
-			}
-		},
-		props: {
-			// 是否开启长按拖动
-			isLongTouch: {
-				value: Boolean,
-				default: true
-			},
-			longTouchTime: {
-				value: Number,
-				default: 300
-			},
-			// 列表数据
-			list: {
-				value: Array,
-				default: []
-			},
-			// 行高度 默认44行高
-			rowHeight: {
-				value: Number,
-				default: 44
-			},
-			// 组件高度 默认windowHeight满屏
-			listHeight: {
-				value: Number,
-				default: 0
-			}
-		},
-		watch: {
-			list: {
-				handler(val) {
-					this.initList(); //数据变化重新初始化list
-				},
-				immediate: true
-			}
-
-		},
-		mounted() {
-			if (this.listHeight == 0) {
-				this.ListHeight = uni.getSystemInfoSync().windowHeight;
-			}
-
-		},
-		methods: {
-      // 触底
-      scrolltolower(){
-        this.$emit('scrolltolower')
-      },
-
-			loadShadowRow(e) {
-				this.shadowRow = JSON.parse(JSON.stringify(this.dragList[this.listSwitch ? "A" : "B"][e.rowIndex]));
-			},
-			initList() {
-				if (this.dragList.A.length > 0) {
-					setTimeout(() => {
-						this.dragList.A = JSON.parse(JSON.stringify(this.list));
-						this.dragList.B = JSON.parse(JSON.stringify(this.list));
-					}, 50)
-				} else {
-					this.dragList.A = JSON.parse(JSON.stringify(this.list));
-					this.dragList.B = JSON.parse(JSON.stringify(this.list));
-				}
-
-			},
-			triggerClick(index, row) {
-				this.$emit('onclick', {
-					index: index,
-					value: JSON.parse(JSON.stringify(row))
-				});
-			},
-			//兼容微信小程序震动
-			vibrate() {
-				uni.vibrateShort()
-			},
-			// 控制自动滚动视图
-			pageScroll(e) {
-				// 滚动
-				if (e.command == "up" || e.command == "down") {
-					if (!this.isHoldTouch) {
-						this.isHoldTouch = true;
-						this.scrollViewTop = e.scrollTop;
-					}
-					if (this.isScrolling) {
-						return;
-					};
-					this.isScrolling = true;
-
-					// APP端和H5端 执行renderjs的滚动
-					// #ifdef APP-PLUS || H5
-					e.ListHeight = this.ListHeight;
-					e.rowHeight = this.rowHeight;
-					e.rowLength = this.list.length;
-					this.scrollCommand = e;
-					return;
-					// #endif
-
-					// 微信小程序执行以下逻辑
-					this.scrollTimer != null && clearInterval(this.scrollTimer);
-					let maxheight = this.rowHeight * this.list.length + 1 - this.ListHeight;
-					// 16.6ms毫秒执行一次,接近60HZ
-					this.scrollTimer = setInterval(() => {
-						if (e.command == "up") {
-							this.scrollViewTop -= 3
-						}
-						if (e.command == "down") {
-							this.scrollViewTop += 3;
-						}
-						if (this.scrollViewTop < 0) {
-							this.scrollViewTop = 0;
-							clearInterval(this.scrollTimer);
-						}
-						if (this.scrollViewTop > maxheight) {
-							this.scrollViewTop = maxheight;
-							clearInterval(this.scrollTimer);
-						}
-					}, 16.6)
-				}
-				// 停止滚动
-				if (e.command == "stop") {
-					// #ifdef APP-PLUS || H5
-					this.scrollCommand = e;
-					// #endif
-					this.isScrolling && this.stopScroll();
-				}
-			},
-			stopScroll() {
-				this.scrollTimer != null && clearInterval(this.scrollTimer);
-				this.isScrolling = false;
-				this.scrollingtop = 0;
-			},
-			change(e) {
-				e.moveRow = JSON.parse(JSON.stringify(this.dragList.A[e.index]))
-				this.$emit('change', e);
-			},
-			sort(e) {
-				this.stopScroll();
-				this.isHoldTouch = false;
-				let tmpList = JSON.parse(JSON.stringify(this.dragList.A));
-				tmpList.splice(e.offset, 0, tmpList.splice(e.index, 1)[0]);
-				let listType = "A"
-				if (this.listSwitch) {
-					this.dragList.B = [];
-					this.dragList.B = tmpList;
-
-				} else {
-					this.dragList.A = [];
-					this.dragList.A = tmpList;
-					listType = "B";
-				}
-				setTimeout(() => {
-					this.resetList(listType, tmpList)
-				}, 50)
-				this.$emit('confirm', {
-					list: tmpList,
-					index: e.index,
-					moveTo: e.offset,
-					moveRow: JSON.parse(JSON.stringify(this.dragList.A[e.index]))
-				});
-			},
-			resetList(listType, tmpList) {
-				this.listSwitch = !this.listSwitch;
-				this.$nextTick(() => {
-					this.dragList[listType] = [];
-					this.dragList[listType] = tmpList;
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-.chart-list-wrap{
-  .hide{
-    display: none;
-  }
-  .show{
-    
-  }
-}
-.chart-list{
-  padding: 24rpx 25rpx;
-  width: 100%;
-  box-sizing: border-box;
-  display: flex;
-  justify-content: space-between;
-  flex-wrap: wrap;
-  .chart-item{
-    width: 48.5%;
-    &.show{
-      display: block;
-    }
-    &.hide{
-      display: none;
-    }
-    .row{
-      background: #FFFFFF;
-      box-shadow: 0px 0px 12rpx rgba(154, 141, 123, 0.16);
-      border-radius: 8rpx;
-      margin-bottom: 20rpx;
-      padding: 20rpx 20rpx 33rpx 20rpx;
-      position: relative;
-    }
-    .title{
-      font-size: 26rpx;
-    }
-    .img{
-      margin-top: 10rpx;
-      width: 100%;
-      height: 261rpx;
-      display: block;
-      margin-left: auto;
-      margin-right: auto;
-      background-color: #f6f6f6;
-    }
-
-    .drag-icon{
-      position: absolute;
-      top: 0;
-      right: 0;
-      width: 40rpx !important;
-      height: 40rpx !important;
-    }
-  }
-
-}
-
-.shadowRowBox{
-    &.show{
-      display: block;
-      opacity: 0.7;
-    }
-    width: 48vw;
-    background: #FFFFFF;
-    box-shadow: 0px 0px 12rpx rgba(154, 141, 123, 0.16);
-    border-radius: 8rpx;
-    margin-bottom: 20rpx;
-    padding: 20rpx 20rpx 33rpx 20rpx;
-    position: absolute;
-		z-index: 100;
-		display: none;
-    .title{
-      font-size: 26rpx;
-    }
-    .img{
-      margin-top: 10rpx;
-      width: 100%;
-      height: 261rpx;
-      display: block;
-      margin-left: auto;
-      margin-right: auto;
-      background-color: #f6f6f6;
-    }
-
-    .drag-icon{
-      position: absolute;
-      top: 0;
-      right: 0;
-      width: 40rpx;
-      height: 40rpx;
-    }
-}
-</style>

+ 0 - 273
components/chartList/drag.wxs

@@ -1,273 +0,0 @@
-var row_Height = 0;			//行高
-var scrollOffsetTop = 0;	//滚动条位置
-var isAppH5 = false;		//是否APPH5端
-var isLongTouch = false;	//是否开启长按
-var longTouchTime = 350;	//触发长安事件事件
-var isMove = false;			//是否可拖动
-var touchTimer=false;		//长按事件定时器
-function scroll(event,instance){
-	scrollOffsetTop = event.detail.scrollTop;
-}
-function touchstart(event, instance) {
-	isMove = false;
-	if(row_Height==0){
-		var rowStyle = event.instance.getComputedStyle(['height']);
-		row_Height = parseInt(rowStyle.height);//获取行高
-		console.log(rowStyle.height)
-	}
-	var rowData = event.instance.getDataset();
-	var rowtype = rowData.type == "A" ? "B" : "A";
-	//重置样式
-	resetRowStyle(state, instance, rowtype);
-	var state = instance.getState();
-	if (event.touches.length == 1) {
-		state.point = event.touches[0];
-		state.initscrollOffsetTop = scrollOffsetTop;
-		state.islongTap = true;
-		state.rowData = rowData;
-		//读取数据
-		var dataViewDOM = instance.selectComponent('#dataView');
-		var viewData = dataViewDOM.getDataset();
-		isAppH5 = viewData.isapph5&&JSON.parse(viewData.isapph5);
-		isLongTouch = viewData.islongtouch&&JSON.parse(viewData.islongtouch);
-		longTouchTime = parseInt(viewData.longtouchtime);
-		state.rowData.rownum = viewData.rownum;
-		state.rowData.listheight = viewData.listheight;
-	}
-	
-	// 计算shadowRow.style.top
-	var rowIndex = parseInt(rowData.index);
-	var shadowRowTop = rowIndex*row_Height;
-	shadowRowTop = shadowRowTop - scrollOffsetTop;
-	// 加载shadowRow数据
-	instance.callMethod("loadShadowRow", {rowIndex : rowIndex,shadowRowTop:shadowRowTop});
-	state.shadowRowTop = shadowRowTop;
-	var shadowBoxComponent = instance.selectComponent('#shadowRowBox');
-	shadowBoxComponent.setStyle({'top': shadowRowTop + 'px'})
-	//长按事件
-	if(isLongTouch){
-		if(typeof setTimeout !== "undefined"){
-			touchTimer && clearTimeout(touchTimer);
-			touchTimer = setTimeout(function(){
-				longpress(event,instance);
-			},longTouchTime)
-		}
-	}
-}
-function longpress(event,instance){
-	if(isLongTouch){
-		isMove = true;
-		moveRow(instance, 0)
-	}
-}
-function touchmove(event, instance) {
-	
-	var state = instance.getState();
-	var rowData = event.instance.getDataset(); 
-	var movePoint = event.touches[0];
-	var initPoint = state.point;
-	var moveY = movePoint.pageY - initPoint.pageY;	
-	//xy
-	var moveX=movePoint.pageX-initPoint.pageX
-
-
-
-	if(isLongTouch){
-		if(typeof setTimeout !== "undefined" && Math.abs(moveY)>10){
-			clearTimeout(touchTimer);
-		}
-		if (!isMove) {
-			return ;
-		}
-	}
-	moveRow(instance, moveY,moveX);
-	//阻止滚动页面
-	if(event.preventDefault){
-		event.preventDefault();
-	}
-	return false;
-}
-
-function touchend(event, instance) {
-	if(isLongTouch && typeof setTimeout !== "undefined"){
-		clearTimeout(touchTimer);
-	}
-	
-	if(lastCommand!="stop"){
-		lastCommand = "stop";
-		instance.callMethod("pageScroll", {'command':"stop"});
-	}
-	var state = instance.getState();
-	var rowtype = state.rowData.type;
-	
-	if (typeof state.offset !== "undefined" && state.rowData.index != state.offset && state.offset != null) {
-		instance.callMethod("sort", {
-			index: state.rowData.index,
-			offset: state.offset
-		});
-	} else {
-		resetRowStyle(state, instance, rowtype);
-		resetShadowRowStyle(instance)
-		feedbackGenerator(instance); //震动反馈
-		return false;
-	}
-	resetShadowRowStyle(instance)
-	typeof setTimeout !== "undefined" && setTimeout(function() {
-		resetRowStyle(state, instance, rowtype);
-	}, 500);
-	state.offset = null;
-	oldOffset = null;
-	feedbackGenerator(instance); //震动反馈
-	return false;
-}
-
-function resetRowStyle(state, instance, rowtype) {
-	var blockList = instance.selectAllComponents('.row'+rowtype);
-	for (var i = 0; i < blockList.length; i++) {
-		blockList[i].setStyle({
-			'height': row_Height+'px',
-			'transform': 'none',
-			'-webkit-transform': 'none'
-			});
-		blockList[i].removeClass('ani');
-		blockList[i].removeClass('hide');
-	}
-}
-function resetShadowRowStyle(instance) {
-	var shadowBoxComponent = instance.selectComponent('#shadowRowBox');
-	shadowBoxComponent.removeClass('show');
-	shadowBoxComponent.setStyle({});
-	shadowBoxComponent.removeClass('move');
-}
-var lastCommand = '';
-// move Row 
-function moveRow(instance, moveY,moveX) {
-	var state = instance.getState();
-	var initIndex = parseInt(state.rowData.index);
-	var rowtype = state.rowData.type;
-	//显示拖拽行Box
-	var shadowBoxComponent = instance.selectComponent('#shadowRowBox');
-	shadowBoxComponent.hasClass('show') || shadowBoxComponent.addClass('show');
-	//隐藏列表对应行
-	var rowDom = instance.selectComponent('#row' + rowtype + state.rowData.index);
-	rowDom.hasClass('hide') || rowDom.addClass('hide');
-	//拖动shadowRow
-	var shadowRowDom = instance.selectComponent('#shadowRow');
-	shadowRowDom.hasClass('move') || shadowRowDom.addClass('move');
-	shadowRowDom.removeClass('ani');
-	var style = {
-		'transform': 'translateY(' + moveY + 'px) translateX('+ moveX +'px) translateZ(10px)',
-		'-webkit-transform': 'translateY(' + moveY + 'px) translateX('+ moveX +'px) translateZ(10px)'
-	}
-	shadowRowDom.setStyle(style); 
-	
-	var listheight = state.rowData.listheight
-	var listClientY = state.shadowRowTop + moveY;
-	var tmpscrollListTop = scrollOffsetTop;
-	// 拖拽至边缘滚动视图 距离顶部距离1.5行高触发上滚动 下滚动同理
-	var callMethodData = {
-		command:listClientY<row_Height*1.5?"up":listClientY>listheight-(row_Height*1.5)?"down":"stop",
-		scrollTop:tmpscrollListTop,
-	}
-	//把滚动指令发给逻辑层
-	if(lastCommand!=callMethodData.command){
-		lastCommand = callMethodData.command;
-		instance.callMethod("pageScroll", callMethodData);
-	}
-	
-	var moveOffset = moveY + scrollOffsetTop - state.initscrollOffsetTop;
-	var offset = calcOffset(initIndex, moveOffset);
-	if(offset<=2 || offset>=state.rowData.rownum-2){
-		callMethodData.command = 'stop';
-	}
-	//为保证体验,非APP和H5端,在滚动视图期间不进行位置交换
-	if((!isAppH5) && callMethodData.command!='stop'){
-		return;
-	}
-	oldOffset = oldOffset == null ? initIndex : oldOffset;
-	if (offset < 0 || offset >= state.rowData.rownum) {
-		return;
-	}
-	if (offset == oldOffset) {
-		return;
-	}
-	
-	oldOffset = offset;
-	state.offset = offset;
-	//触发change事件
-	instance.callMethod("change", {
-		index: state.rowData.index,
-		moveTo: state.offset
-	});
-	feedbackGenerator(instance); //震动反馈
-	//根据offset对行进行位置交换
-	var blockList = instance.selectAllComponents('.row' + rowtype);
-	for (var i = 0; i < blockList.length; i++) {
-		if (i == initIndex) {
-			continue;
-		}
-		var translateY = 0;
-		if ((i >= offset && i < initIndex) || (i <= offset && i > initIndex)) {
-			translateY = i < initIndex ? row_Height : -row_Height;
-		}
-		var style = {
-			'height': row_Height+'px',
-			'transform': 'translateY(' + translateY + 'px) translateZ(5px)',
-			'-webkit-transform': 'translateY(' + translateY + 'px) translateZ(5px)'
-		}
-		blockList[i].hasClass('ani') || blockList[i].addClass('ani');
-		blockList[i].setStyle(style);
-	}
-	
-}
-//计算偏移index
-var oldOffset = null;
-function calcOffset(initIndex, moveY) {
-	var offset = initIndex + parseInt(moveY / row_Height); //偏移 行高的倍数
-	var rest = moveY % row_Height;
-	if (rest > 0) {
-		offset = offset + (rest / row_Height >= 0.6 ? 1 : 0);
-		if (offset < oldOffset) {
-			offset = rest / row_Height <= 0.4 ? offset : oldOffset;
-		}
-	} else {
-		offset = offset + (rest / row_Height <= -0.6 ? -1 : 0);
-		if (offset > oldOffset) {
-			offset = rest / row_Height >= -0.4 ? offset : oldOffset;
-		}
-	}
-	return offset;
-}
-
-//触感反馈
-//wxs 不支持条件编译,所以用此方法判断
-var isiOSAPP = typeof plus != "undefined" && plus.os.name == 'iOS';
-var UISelectionFeedbackGenerator;
-var UIImpactFeedbackGenerator;
-var impact
-
-if (isiOSAPP) {
-	UISelectionFeedbackGenerator = plus.ios.importClass("UISelectionFeedbackGenerator");
-	impact = new UISelectionFeedbackGenerator();
-	impact.init();
-}
-
-function feedbackGenerator(instance) {
-	if (isiOSAPP) {
-		impact.selectionChanged();
-	} else {
-		if (typeof plus != "undefined") {
-			plus.device.vibrate(12)
-		} else {
-			instance.callMethod("vibrate");
-		}
-	}
-}
-
-module.exports = {
-	scroll:scroll,
-	longpress:longpress,
-	touchstart: touchstart,
-	touchmove: touchmove,
-	touchend: touchend
-}

+ 81 - 0
pages-chart/allTypes.vue

@@ -0,0 +1,81 @@
+<template>
+    <view class="chart-alltype-page">
+        <van-sticky style="background: #fff">
+            <van-search
+                shape="round"
+                :value="searchVal"
+                placeholder="图表分类搜索"
+                @change="searchValChange"
+                @search="onSearch"
+                @clear="onClearSearch"
+            />
+        </van-sticky>
+        <view class="list-wrap">
+          <van-collapse :value="active" @change="change" :border="false">
+            <van-collapse-item title="公共图库" name="common" :border="false">
+              <view class="list">
+                <view class="item">分类一</view>
+                <view class="item">分类一</view>
+                <view class="item">分类一</view>
+              </view>
+            </van-collapse-item>
+            <van-collapse-item title="我的图库" name="mine" :border="false">
+              <view class="list">
+                <view class="item">分类一</view>
+                <view class="item">分类一</view>
+                <view class="item">分类一</view>
+              </view>
+            </van-collapse-item>
+          </van-collapse>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      searchVal:'',
+      active:['common','mine']
+    }
+  },
+  methods: {
+    change(e){
+      this.active=e.detail
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.chart-alltype-page{
+  .van-cell__title, .van-cell__value{
+    flex: none !important;
+  }
+  .van-cell:after{
+    border: none !important;
+  }
+  .van-collapse-item__content{
+    padding: 0;
+  }
+  .van-cell__title{
+    font-size: 16px;
+    font-weight: bold;
+  }
+  .van-hairline--top:after{
+    border-top-width: 0 !important;
+  }
+  .list{
+    .item{
+      &:first-child{
+        border-top: 1px solid #E5E5E5;
+      }
+      padding: 20rpx 34rpx;
+      border-bottom: 1px solid #E5E5E5;
+      color: #1F243A;
+      font-size: 14px;
+    }
+  }
+}
+
+</style>

+ 16 - 1
pages.json

@@ -98,6 +98,18 @@
 					}
 				}
 			]
+		},
+		// 图库模块
+		{
+			"root": "pages-chart",
+			"pages": [
+				{
+					"path": "allTypes",
+					"style":{
+						"navigationBarTitleText": "图表分类"
+					}
+				}
+			]
 		}
 	],
 		
@@ -146,6 +158,7 @@
 		"navigationBarBackgroundColor": "#FFFFFF",
 		"backgroundColor": "#FFFFFF",
 		"usingComponents":{
+			"drag":"/wxcomponents/drag/index",
 			"van-button":"/wxcomponents/vant/button/index",
 			"van-toast":"/wxcomponents/vant/toast/index",
 			"van-popup":"/wxcomponents/vant/popup/index",
@@ -159,7 +172,9 @@
 			"van-count-down": "/wxcomponents/vant/count-down/index",
 			"van-empty": "/wxcomponents/vant/empty/index",
 			"van-checkbox": "/wxcomponents/vant/checkbox/index",
-			"van-transition": "/wxcomponents/vant/transition/index"
+			"van-transition": "/wxcomponents/vant/transition/index",
+			"van-collapse": "/wxcomponents/vant/collapse/index",
+  		"van-collapse-item": "/wxcomponents/vant/collapse-item/index"
 		}
 	}
 }

+ 42 - 177
pages/chart/chart.vue

@@ -20,62 +20,19 @@
             />
         </view>
       </van-sticky>
-      <!-- <view class="flex chart-list">
-        <view 
-          class="chart-item" 
-          v-for="(item,index) in list" 
-          :key="item"
-          @longpress="longtap(item)"
-          @touchstart="touchstart"
-          @touchmove.stop.prevent="touchmove"
-          @touchend="touchend(item)"
-        >
-          <rich-text 
-            class="van-multi-ellipsis--l2 title" 
-            :nodes="getTitle('标题'+item.title+index)" 
-            @longpress="chartItemLongPress(item,$event)"
-          ></rich-text>
-          <image lazy-load class="img" src="" mode="aspectFill"/>
-        </view>
-
-        <view v-show="popData.show" class="pop-box" :style="{top:popData.y+'px',left:popData.x+'px'}">{{popData.title}}</view>
-
-        <view class="move-active-chart" v-show="moveData.show" :style="{top:moveData.y+'px',left:moveData.x+'px'}">
-          <rich-text 
-            class="van-multi-ellipsis--l2 title" 
-            :nodes="getTitle('标题'+moveData.chart.title)" 
-          ></rich-text>
-          <image lazy-load class="img" src="" mode="aspectFill"/>
-        </view>
-      </view> -->
-
-
-      <chartList
-        v-if="chartH"
-        :list="list" 
-        :isLongTouch="false" 
-        :isAutoScroll="true" 
-        :feedbackGeneratorState="true"  
-        :rowHeight="200" 
-        :listHeight="chartH"
-        @change="change" 
-        @confirm="confirm" 
-        @onclick="onclick"
-        @scrolltolower="scrolltolower"
-      >
-      </chartList>
-    
-      <!-- <DragSorts
-        @change="sortChange"
-        @click="click"
-        @del="moduleDel"
-        :viewWidth="375"
-        :height="200"
-        :row="2"
-        :disabled="false"
-        :list="list"
-      >
-      </DragSorts> -->
+      <view class="chart-list-wrap">
+        <drag
+          ref="chartDrag"
+          generic:item="chart-item"
+          :columns="2"
+          :list-data="list"
+          @sortend="chartSortend"
+          @change="chartChange"
+          @click="chartClick"
+        ></drag>
+      </view>
+      
+      
     
     </view>
     
@@ -90,7 +47,7 @@
       >
         <view class="filter-wrap">
           <view class="top">
-            <text class="left">展开</text>
+            <text class="left" @click="goAllTypes">展开</text>
             <text class="center">全部筛选</text>
           </view>
           <view class="filter-list">
@@ -105,31 +62,22 @@
 </template>
 
 <script>
-import chartList from '../../components/chartList/chartList.vue'
-// import DragSorts from "../../components/evils-drag-sorts/index.vue";
+import chartItem from './component/chartItem.vue'
 export default {
     components: {
-      chartList
-      // DragSorts
+      'chart-item':chartItem
     },
     data() {
         return {
           showFilter:false,//显示筛选弹窗
-          popData:{
-            show:false,
-            x:0,
-            y:0,
-            title:''
-          },//长按标题弹窗
 
           list:[],
           page:1,
           finished:false,
-          chartH:0,
+          chartDrag:null,
         }
     },
     onLoad() {
-      this.initListHeight()
       this.getList()
     },
     
@@ -139,66 +87,42 @@ export default {
         // this.getList()
     },
     methods: {
-      // 计算出图列表高度
-      initListHeight(){
-        let searchH=0
-        const query = uni.createSelectorQuery().in(this);
-        query.select('#search-wrap').boundingClientRect(data => {
-          searchH=data.height
-        }).exec();
-
-        query.select('.chart-page').boundingClientRect(data => {
-          this.chartH=data.height-searchH
-        }).exec();
-
-      },
-
-      scrolltolower(){
-        if (this.finished) return
-        this.page++
-        this.getList()
-      },
-
-      change(e){
-        console.log(e);
-      },
-
-      confirm(e){},
-      onclick(e){},
-
       // 获取列表
       getList(){
         if(this.page<5){
           let arr=[]
           for (let index = (this.page-1)*20; index < this.page*20; index++) {
-            arr.push({title:'标题'+index,src:''})
+            arr.push({title:'标题'+index,src:'',dragId:'chart'+index,fixed: false})
           }
           this.list=[...this.list,...arr]
+          setTimeout(() => {
+            this.chartDrag=this.$refs.chartDrag
+            this.chartDrag.init();
+          }, 100);
         }else{
           this.finished=true
         }
         
       },
 
-      chartItemLongPress(item,e){
+      chartSortend(e){
+        console.log(e);
+      },
+      chartChange(e){
+        console.log(e);
+      },
+      chartClick(e){
         console.log(e);
-        this.popData.show=true
-        this.popData.title=item
-        this.popData.x=e.detail.x 
-        this.popData.y=e.detail.y
-        uni.setClipboardData({
-            data: item,
-            success: function () {
-                uni.showToast({
-                  title: '复制成功',
-                  icon: 'none',
-                })
-            },
-            fail:function(e){
-              console.log(e);
-            }
-        });
-      }
+      },
+
+      // 跳转全部分类
+      goAllTypes(){
+        uni.navigateTo({ 
+          url: '/pages-chart/allTypes'
+        })
+        this.showFilter=false
+      },
+      
     }
 }
 </script>
@@ -225,68 +149,9 @@ export default {
       padding: 0;
     }
 }
-
-// .chart-list{
-//   padding: 24rpx 25rpx;
-//   width: 100%;
-//   height: 67vh;
-//   box-sizing: border-box;
-//   justify-content: space-between;
-//   flex-wrap: wrap;
-//   .chart-item{
-//     width: 48.5%;
-//     background: #FFFFFF;
-//     box-shadow: 0px 0px 12rpx rgba(154, 141, 123, 0.16);
-//     border-radius: 8rpx;
-//     margin-bottom: 20rpx;
-//     padding: 20rpx 20rpx 33rpx 20rpx;
-//     .title{
-//       font-size: 26rpx;
-//     }
-//     .img{
-//       margin-top: 10rpx;
-//       width: 100%;
-//       height: 261rpx;
-//       display: block;
-//       margin-left: auto;
-//       margin-right: auto;
-//       background-color: #f6f6f6;
-//     }
-//   }
-
-//   .pop-box{
-//     background-color: #fff;
-//     width: 100rpx;
-//     font-size: 14px;
-//     padding: 10rpx;
-//     border-radius: 4rpx;
-//     position: absolute;
-//     box-shadow: 0px 0px 12rpx rgba(154, 141, 123, 0.16);
-//   }
-
-//   .move-active-chart{
-//     position: absolute;
-//     opacity: 0.5;
-//     width: 48.5%;
-//     background: #FFFFFF;
-//     box-shadow: 0px 0px 12rpx rgba(154, 141, 123, 0.16);
-//     border-radius: 8rpx;
-//     padding: 20rpx 20rpx 33rpx 20rpx;
-//     .title{
-//       font-size: 26rpx;
-//     }
-//     .img{
-//       margin-top: 10rpx;
-//       width: 100%;
-//       height: 261rpx;
-//       display: block;
-//       margin-left: auto;
-//       margin-right: auto;
-//       background-color: #f6f6f6;
-//     }
-//   }
-
-// }
+.chart-list-wrap{
+  padding: 24rpx 15rpx;
+}
 
 .filter-wrap{
   .top{

+ 43 - 0
pages/chart/component/chartItem.vue

@@ -0,0 +1,43 @@
+<template>
+  <view class="chart-item">
+      <view class="van-multi-ellipsis--l2 title">{{itemData.title}}</view>
+      <image lazy-load class="img" src="" mode="aspectFill"/>
+  </view>
+</template>
+
+<script>
+export default {
+    name:"chartItem",
+    props: {
+        itemData:{
+            type: Object,
+			value: {}
+        }
+    }
+}
+</script>
+
+<style lang='scss' scoped>
+.chart-item{
+    background: #FFFFFF;
+    box-shadow: 0px 0px 12rpx rgba(154, 141, 123, 0.16);
+    border-radius: 8rpx;
+    margin-left: 10rpx;
+    margin-right: 10rpx;
+    margin-bottom: 20rpx;
+    padding: 20rpx 20rpx 33rpx 20rpx;
+    .title{
+      font-size: 26rpx;
+      min-height: 60rpx;
+    }
+    .img{
+      margin-top: 10rpx;
+      width: 100%;
+      height: 261rpx;
+      display: block;
+      margin-left: auto;
+      margin-right: auto;
+      background-color: #f6f6f6;
+    }
+}
+</style>

+ 1 - 0
utils/request.js

@@ -92,6 +92,7 @@ const http=(url,params,method)=>{
 			},
 			success(e) {
 				let res=JSON.parse(CryptoJS.Des3Decrypt(e.data));//解密
+				// let res=e.data
 				if(res.code!==200&&res.code!==403&&res.code!==4001&&res.code!==401){
 					showError(res)
 				}

+ 219 - 0
wxcomponents/drag/index.js

@@ -0,0 +1,219 @@
+/**
+ * 版本号比较
+ */
+const compareVersion = (v1, v2) => {
+	v1 = v1.split('.')
+	v2 = v2.split('.')
+	const len = Math.max(v1.length, v2.length)
+
+	while (v1.length < len) {
+		v1.push('0')
+	}
+	while (v2.length < len) {
+		v2.push('0')
+	}
+
+	for (let i = 0; i < len; i++) {
+		const num1 = parseInt(v1[i])
+		const num2 = parseInt(v2[i])
+
+		if (num1 > num2) {
+			return 1
+		} else if (num1 < num2) {
+			return -1
+		}
+	}
+
+	return 0
+}
+
+Component({
+	externalClasses: ['item-wrap-class'],
+	options: {
+		multipleSlots: true
+	},
+	properties: {
+		extraNodes: {            // 额外节点
+			type: Array,
+			value: []
+		},
+		listData: {              // 数据源
+			type: Array,
+			value: []
+		},
+		columns: {               // 列数
+			type: Number,
+			value: 1
+		},
+		topSize: {               // 顶部固定高度
+			type: Number,
+			value: 0
+		},
+		bottomSize: {            // 底部固定高度
+			type: Number,
+			value: 0
+		},
+		itemHeight: {            // 每个 item 高度, 用于计算 item-wrap 高度
+			type: Number,
+			value: 0
+		},
+		scrollTop: {             // 页面滚动高度
+			type: Number,
+			value: 0
+		},
+	},
+	data: {
+		/* 未渲染数据 */
+		baseData: {},
+		pageMetaSupport: false,                                 // 当前版本是否支持 page-meta 标签
+		platform: '',                                           // 平台信息
+		listWxs: [],                                            // wxs 传回的最新 list 数据
+		rows: 0,                                                // 行数
+
+		/* 渲染数据 */
+		wrapStyle: '',                                          // item-wrap 样式
+		list: [],                                               // 渲染数据列
+		dragging: false,
+	},
+	methods: {
+		vibrate() {
+			if (this.data.platform !== "devtools") wx.vibrateShort();
+		},
+		pageScroll(e) {
+			if (this.data.pageMetaSupport) {
+				this.triggerEvent("scroll", {
+					scrollTop: e.scrollTop
+				});
+			} else {
+				wx.pageScrollTo({
+					scrollTop: e.scrollTop,
+					duration: 300
+				});
+			}
+		},
+		drag(e) {
+			this.setData({
+				dragging: e.dragging
+			})
+		},
+		listChange(e) {
+			this.data.listWxs = e.list;
+		},
+		itemClick(e) {
+			let index = e.currentTarget.dataset.index;
+			let item = this.data.listWxs[index];
+
+			this.triggerEvent('click', {
+				key: item.realKey,
+				data: item.data,
+				extra: e.detail
+			});
+		},
+		/**
+		 *  初始化获取 dom 信息
+		 */
+		initDom() {
+			let {windowWidth, windowHeight, platform, SDKVersion} = wx.getSystemInfoSync();
+			let remScale = (windowWidth || 375) / 375;
+
+			this.data.pageMetaSupport = compareVersion(SDKVersion, '2.9.0') >= 0;
+			this.data.platform = platform;
+
+			let baseData = {};
+			baseData.windowHeight = windowHeight;
+			baseData.realTopSize = this.data.topSize * remScale / 2;
+			baseData.realBottomSize = this.data.bottomSize * remScale / 2;
+			baseData.columns = this.data.columns;
+			baseData.rows =  this.data.rows;
+
+			const query = this.createSelectorQuery();
+			query.select(".item").boundingClientRect();
+			query.select(".item-wrap").boundingClientRect();
+			query.exec((res) => {
+				baseData.itemWidth = res[0].width;
+				baseData.itemHeight = res[0].height;
+				baseData.wrapLeft = res[1].left;
+				baseData.wrapTop = res[1].top + this.data.scrollTop;
+				this.setData({
+					dragging: false,
+					baseData
+				});
+			});
+		},
+		/**
+		 * column 改变时候需要清空 list, 以防页面溢出
+		 */
+		columnChange() {
+			this.setData({
+				list: []
+			})
+			this.init();
+		},
+		/**
+		 *  初始化函数
+		 *  {listData, topSize, bottomSize, itemHeight} 参数改变需要手动调用初始化方法
+		 */
+		init() {
+			// 初始必须为true以绑定wxs中的函数,
+			this.setData({dragging: true});
+
+			let delItem = (item, extraNode) => ({
+				id: item.dragId,
+				extraNode: extraNode,
+				fixed: item.fixed,
+				slot: item.slot,
+				data: item
+			});
+
+			let {listData, extraNodes} = this.data;
+			let _list = [], _before = [], _after = [], destBefore = [], destAfter = [];
+
+			extraNodes.forEach((item, index) => {
+				if (item.type === "before") {
+					_before.push(delItem(item, true));
+				} else if (item.type === "after") {
+					_after.push(delItem(item, true));
+				} else if (item.type === "destBefore") {
+					destBefore.push(delItem(item, true));
+				} else if (item.type === "destAfter") {
+					destAfter.push(delItem(item, true));
+				}
+			});
+
+			// 遍历数据源增加扩展项, 以用作排序使用
+			listData.forEach((item, index) => {
+				destBefore.forEach((i) => {
+					if (i.data.destKey === index) _list.push(i);
+				});
+				_list.push(delItem(item, false));
+				destAfter.forEach((i) => {
+					if (i.data.destKey === index) _list.push(i);
+				});
+			});
+
+			let i = 0, columns = this.data.columns;
+			let list = (_before.concat(_list, _after) || []).map((item, index) => {
+				item.realKey = item.extraNode ? -1 : i++; // 真实顺序
+				item.sortKey = index; // 整体顺序
+				item.tranX = `${(item.sortKey % columns) * 100}%`;
+				item.tranY = `${Math.floor(item.sortKey / columns) * 100}%`;
+				return item;
+			});
+
+			this.data.rows = Math.ceil(list.length / columns);
+
+			this.setData({
+				list,
+				listWxs: list,
+				wrapStyle: `height: ${this.data.rows * this.data.itemHeight}rpx`
+			});
+			if (list.length === 0) return;
+
+			// 异步加载数据时候, 延迟执行 initDom 方法, 防止基础库 2.7.1 版本及以下无法正确获取 dom 信息
+			setTimeout(() => this.initDom(), 0);
+		}
+	},
+	ready() {
+		this.init();
+	}
+});

+ 6 - 0
wxcomponents/drag/index.json

@@ -0,0 +1,6 @@
+{
+	"component": true,
+	"componentGenerics": {
+		"item": true
+	}
+}

+ 20 - 0
wxcomponents/drag/index.scss

@@ -0,0 +1,20 @@
+@import "../../assets/css/variables";
+
+.item-wrap {
+	position: relative;
+	.item {
+		position: absolute;
+		z-index: 1;
+		top: 0;
+		left: 0;
+		&.tran {
+			transition: transform 0.3s !important;
+		}
+		&.cur {
+			z-index: 2;
+		}
+		&.fixed {
+			z-index: 0 !important;
+		}
+	}
+}

+ 28 - 0
wxcomponents/drag/index.wxml

@@ -0,0 +1,28 @@
+<wxs module="handler" src="./index.wxs"></wxs>
+
+<view class="item-wrap item-wrap-class"
+			list="{{list}}"
+			style="{{wrapStyle}}"
+			baseData="{{baseData}}"
+			change:list="{{handler.listObserver}}"
+			change:baseData="{{handler.baseDataObserver}}">
+
+	<view
+		class="item"
+		wx:for="{{list}}"
+		wx:key="id"
+		data-index="{{index}}"
+		style="width: {{100/columns}}%"
+		bind:longpress="{{handler.longPress}}"
+		catch:touchmove="{{dragging ? handler.touchMove : ''}}"
+		catch:touchend="{{dragging ? handler.touchEnd : ''}}">
+
+		<block wx:if="{{item.extraNode}}">
+			<slot name="{{item.slot}}"></slot>
+		</block>
+		<block wx:else>
+			<item data-index="{{index}}" columns="{{columns}}" item-data="{{item.data}}" bind:click="itemClick"/>
+		</block>
+
+	</view>
+</view>

+ 223 - 0
wxcomponents/drag/index.wxs

@@ -0,0 +1,223 @@
+var isOutRange = function (x1, y1, x2, y2, x3, y3) {
+	return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3
+};
+
+var sortCore = function (sKey, eKey, st) {
+	var _ = st.baseData;
+
+	var excludeFix = function (cKey, type) {
+		if (st.list[cKey].fixed) { // fixed 元素位置不会变化, 这里直接用 cKey(sortKey) 获取, 更加快捷
+			type ? --cKey : ++cKey;
+			return excludeFix(cKey, type);
+		}
+		return cKey;
+	}
+
+	// 先获取到 endKey 对应的 realKey, 防止下面排序过程中该 realKey 被修改
+	var endRealKey = -1;
+	st.list.forEach(function (item) {
+		if(item.sortKey === eKey) endRealKey = item.realKey;
+	});
+
+	return st.list.map(function (item) {
+		if (item.fixed) return item;
+		var cKey = item.sortKey;
+		var rKey = item.realKey;
+
+		if (sKey < eKey) {
+			// 正序拖动
+			if (cKey > sKey && cKey <= eKey) {
+				--rKey;
+				cKey = excludeFix(--cKey, true);
+			} else if (cKey === sKey) {
+				rKey = endRealKey;
+				cKey = eKey;
+			}
+		} else if (sKey > eKey) {
+			// 倒序拖动
+			if (cKey >= eKey && cKey < sKey) {
+				++rKey
+				cKey = excludeFix(++cKey, false);
+			} else if (cKey === sKey) {
+				rKey = endRealKey;
+				cKey = eKey;
+			}
+		}
+
+		if (item.sortKey !== cKey) {
+			item.tranX = (cKey % _.columns) * 100 + "%";
+			item.tranY = Math.floor(cKey / _.columns) * 100 + "%";
+			item.sortKey = cKey;
+			item.realKey = rKey;
+		}
+		return item;
+	});
+}
+
+var triggerCustomEvent = function(list, type, ins) {
+	var _list = [], listData = [];
+
+	list.forEach(function (item) {
+		_list[item.sortKey] = item;
+	});
+
+	_list.forEach(function (item) {
+		if (!item.extraNode) {
+			listData.push(item.data);
+		}
+	});
+
+	ins.triggerEvent(type, {listData: listData});
+}
+
+var longPress = function (event, ownerInstance) {
+	var ins = event.instance;
+	var st = ownerInstance.getState();
+	var _ = st.baseData;
+
+	var sTouch = event.changedTouches[0];
+	if (!sTouch) return;
+
+	st.cur = ins.getDataset().index;
+
+	// 初始项是固定项则返回
+	var item = st.list[st.cur];
+	if (item && item.fixed) return;
+
+	// 如果已经在 drag 中则返回, 防止多指触发 drag 动作, touchstart 事件中有效果
+	if (st.dragging) return;
+	st.dragging = true;
+	ownerInstance.callMethod("drag", {dragging: true});
+
+	// 计算X,Y轴初始位移, 使 item 中心移动到点击处, 单列时候X轴初始不做位移
+	st.tranX = _.columns === 1 ? 0 : sTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
+	st.tranY = sTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
+	st.sId = sTouch.identifier;
+
+	ins.setStyle({
+		'transform': 'translate3d(' + st.tranX + 'px, ' + st.tranY + 'px, 0)'
+	});
+
+	st.itemsInstance.forEach(function (item, index) {
+		item.removeClass("tran").removeClass("cur");
+		item.addClass(index === st.cur ? "cur" : "tran");
+	})
+
+	ownerInstance.callMethod("vibrate");
+};
+
+var touchMove = function (event, ownerInstance) {
+	var ins = event.instance;
+	var st = ownerInstance.getState();
+	var _ = st.baseData;
+
+	var mTouch = event.changedTouches[0];
+	if (!mTouch) return;
+
+	if (!st.dragging) return;
+
+	// 如果不是同一个触发点则返回
+	if (st.sId !== mTouch.identifier) return;
+
+	// 计算X,Y轴位移, 单列时候X轴初始不做位移
+	var tranX = _.columns === 1 ? 0 : mTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
+	var tranY = mTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
+
+	// 到顶到底自动滑动
+	if (mTouch.clientY > _.windowHeight - _.itemHeight - _.realBottomSize) {
+		// 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度)
+		ownerInstance.callMethod("pageScroll", {
+			scrollTop: mTouch.pageY + _.itemHeight - (_.windowHeight - _.realBottomSize)
+		});
+	} else if (mTouch.clientY < _.itemHeight + _.realTopSize) {
+		// 当前触摸点pageY - item高度 - 顶部固定区域高度
+		ownerInstance.callMethod("pageScroll", {
+			scrollTop: mTouch.pageY - _.itemHeight - _.realTopSize
+		});
+	}
+
+	// 设置当前激活元素偏移量
+	ins.setStyle({
+		'transform': 'translate3d(' + tranX + 'px, ' + tranY + 'px, 0)'
+	})
+
+	var startKey = st.list[st.cur].sortKey;
+	var curX = Math.round(tranX / _.itemWidth);
+	var curY = Math.round(tranY / _.itemHeight);
+	var endKey = curX + _.columns * curY;
+
+	// 目标项是固定项则返回
+	var item = st.list[endKey];
+	if (item && item.fixed) return;
+
+	// X轴或Y轴超出范围则返回
+	if (isOutRange(curX, _.columns, curY, _.rows, endKey, st.list.length)) return;
+
+	// 防止拖拽过程中发生乱序问题
+	if (startKey === endKey || startKey === st.preStartKey) return;
+	st.preStartKey = startKey;
+
+	var list = sortCore(startKey, endKey, st);
+	st.itemsInstance.forEach(function (itemIns, index) {
+		var item = list[index];
+		if (index !== st.cur) {
+			itemIns.setStyle({
+				'transform': 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)'
+			});
+		}
+	});
+
+	ownerInstance.callMethod("vibrate");
+	ownerInstance.callMethod("listChange", {list: list});
+	triggerCustomEvent(list, "change", ownerInstance);
+}
+
+var touchEnd = function (event, ownerInstance) {
+	var ins = event.instance;
+	var st = ownerInstance.getState();
+
+	if (!st.dragging) return;
+	triggerCustomEvent(st.list, "sortend", ownerInstance);
+
+	ins.addClass("tran");
+	ins.setStyle({
+		'transform': 'translate3d(' + st.list[st.cur].tranX + ',' + st.list[st.cur].tranY + ', 0)'
+	});
+
+	st.preStartKey = -1;
+	st.dragging = false;
+	ownerInstance.callMethod("drag", {dragging: false});
+	st.cur = -1;
+	st.tranX = 0;
+	st.tranY = 0;
+}
+
+var baseDataObserver = function (newVal, oldVal, ownerInstance, ins) {
+	var st = ownerInstance.getState();
+	st.baseData = newVal;
+}
+
+var listObserver = function (newVal, oldVal, ownerInstance, ins) {
+	var st = ownerInstance.getState();
+	st.itemsInstance = ownerInstance.selectAllComponents('.item');
+
+	st.list = newVal || [];
+
+	st.list.forEach(function (item, index) {
+		var itemIns = st.itemsInstance[index];
+		if (item && itemIns) {
+			itemIns.setStyle({
+				'transform': 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)'
+			});
+			if (item.fixed) itemIns.addClass("fixed");
+		}
+	})
+}
+
+module.exports = {
+	longPress: longPress,
+	touchMove: touchMove,
+	touchEnd: touchEnd,
+	baseDataObserver: baseDataObserver,
+	listObserver: listObserver
+}

+ 13 - 0
wxcomponents/drag/index.wxss

@@ -0,0 +1,13 @@
+.item-wrap {
+  position: relative; }
+  .item-wrap .item {
+    position: absolute;
+    z-index: 1;
+    top: 0;
+    left: 0; }
+    .item-wrap .item.tran {
+      transition: transform 0.3s !important; }
+    .item-wrap .item.cur {
+      z-index: 2; }
+    .item-wrap .item.fixed {
+      z-index: 0 !important; }