graceNvueSwipeList.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <view class="grace-swipe-list" :style="{width:width+'rpx'}">
  3. <graceNvueTouch v-for="(item, index) in msgsIn" :key="index" @thStart="thStart" @thMove="thMove" @thEnd="thEnd" :datas="[index]">
  4. <view class="grace-swipe-list-item" :style="{width:width+'rpx'}">
  5. <view class="grace-swipe-list-item-body" :style="{width:width+'rpx', marginLeft:(item.x * -1) + 'px'}">
  6. <view class="grace-swipe-list-img" :style="{width:imgSize[0], height:imgSize[1]}">
  7. <image :src="item.img" mode="widthFix" :style="{width:imgSize[0], height:imgSize[1], borderRadius:'6rpx'}"></image>
  8. <text class="grace-swipe-list-point" v-if="item.msgnumber > 0">{{item.msgnumber}}</text>
  9. </view>
  10. <view class="grace-swipe-list-content">
  11. <view class="grace-swipe-list-title">
  12. <text class="grace-swipe-list-title-text" :style="{fontSize:fontSizes[0], color:fontColors[0], flex:1}">{{item.title}}</text>
  13. <text class="grace-swipe-list-title-text" :style="{fontSize:fontSizes[1], color:fontColors[1], marginLeft:'25rpx', marginRight:'25rpx'}">{{item.time}}</text>
  14. </view>
  15. <text class="grace-swipe-list-desc" :style="{fontSize:fontSizes[2], color:fontColors[2], marginTop:'6rpx'}">{{item.content}}</text>
  16. </view>
  17. </view>
  18. <view class="grace-swipe-btns" :style="{width:item.x+'px'}">
  19. <view class="grace-swipe-btn" v-for="(btn, btnIndex) in item.btns" :key="btnIndex"
  20. :style="{backgroundColor:btn.bgColor}" @tap.stop="btnTap(index, btnIndex)">
  21. <text class="grace-swipe-btn-text">{{btn.name}}</text>
  22. </view>
  23. </view>
  24. </view>
  25. </graceNvueTouch>
  26. </view>
  27. </template>
  28. <script>
  29. export default{
  30. props:{
  31. width:{type:Number, default:750},
  32. msgs:{type:Array,default:function(){return [];}},
  33. imgSize:{type:Array,default:function(){return ['80rpx', '80rpx'];}},
  34. fontSizes:{type:Array,default:function(){return ['28rpx','22rpx', '22rpx'];}},
  35. fontColors:{type:Array,default:function(){return ['#323232','#888888', '#888888'];}},
  36. btnWidth:{type:Number, default:160}
  37. },
  38. data() {
  39. return {
  40. msgsIn: [],
  41. damping : 0.1
  42. }
  43. },
  44. created:function(){
  45. this.init(this.msgs);
  46. },
  47. watch:{
  48. msgs : function(nv){
  49. this.init(nv);
  50. }
  51. },
  52. methods:{
  53. init:function(msgs){
  54. var newmsg = [];
  55. msgs.forEach((item) => { item.x = 0; newmsg.push(item); });
  56. this.msgsIn = newmsg;
  57. },
  58. setItems : function (msgs){
  59. },
  60. thStart : function(e, index){
  61. this.damping = 0.1;
  62. var i = 0;
  63. this.msgsIn.forEach((item) => {
  64. if(i != index){
  65. if(item.x > 10){this.toZero(i);}
  66. }
  67. i++;
  68. });
  69. },
  70. thMove : function (e, index){
  71. var item = this.msgsIn[index];
  72. item.x -= e[0][0] * this.damping;
  73. if(item.x > this.btnWidth){item.x = this.btnWidth;}
  74. if(item.x < 0){item.x = 0;}
  75. this.msgsIn.splice(index, 1, item);
  76. this.damping *= 1.2;
  77. },
  78. thEnd : function(e, index){
  79. if(e[1] < 150){
  80. if(this.msgsIn[index].x >= 5){
  81. this.toZero(index);
  82. return;
  83. }
  84. if(Math.abs(e[0][0]) < 30){this.$emit('itemTap',index);}
  85. return ;
  86. }
  87. var item = this.msgsIn[index];
  88. if(item.x < this.btnWidth / 3){item.x = 0;}else{item.x = this.btnWidth;}
  89. this.msgsIn.splice(index, 1, item);
  90. },
  91. toZero:function(index){
  92. if(this.msgsIn[index].x < 0 ){
  93. this.msgsIn[index].x = 0;
  94. this.msgsIn.splice(index, 1, this.msgs[index]);
  95. return;
  96. }
  97. this.msgsIn[index].x -= 10;
  98. this.msgsIn.splice(index, 1, this.msgsIn[index]);
  99. setTimeout(()=>{this.toZero(index);},10);
  100. },
  101. btnTap : function (index, indexBtn) {
  102. this.$emit('btnTap',index, indexBtn);
  103. }
  104. },
  105. components:{}
  106. }
  107. </script>
  108. <style>
  109. .grace-swipe-list{overflow:hidden;}
  110. .grace-swipe-list-item{overflow:hidden; position:relative;}
  111. .grace-swipe-list-item-body{flex-direction:row; flex-wrap:nowrap; font-size:0; align-items:center;}
  112. .grace-swipe-list-img{flex-shrink:0; margin-left:25rpx; font-size:0;}
  113. .grace-swipe-list-point{border-radius:32rpx; height:30rpx; line-height:30rpx; padding:0 10rpx; font-size:20rpx; background-color:#FF0036; color:#FFFFFF; position:absolute; z-index:1; right:0; top:0;}
  114. .grace-swipe-list-content{width:500rpx; flex:1; overflow:hidden; padding-top:25rpx; padding-bottom:25rpx; margin-left:22rpx; border-bottom-width:1px; border-style:solid; border-color:#F1F2F3;}
  115. .grace-swipe-list-title{flex-direction:row; flex-wrap:nowrap; justify-content:space-between; overflow:hidden;}
  116. .grace-swipe-list-title-text{line-height:38rpx; height:38rpx; overflow:hidden;}
  117. .grace-swipe-list-desc{line-height:32rpx; height:32rpx; overflow:hidden; padding-right:25rpx;}
  118. .grace-swipe-btns{width:0rpx; position:absolute; z-index:1; right:0; top:0; height:116rpx; flex-direction:row; flex-wrap:nowrap;}
  119. .grace-swipe-btn{width:100rpx; flex:1; height:125rpx; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; padding:20rpx; overflow:hidden;}
  120. .grace-swipe-btn-text{line-height:36rpx; height:36rpx; overflow:hidden; font-size:28rpx; color:#FFFFFF;}
  121. </style>