tm-swiperList.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <template>
  2. <view class="tm-swiperList">
  3. <swiper @change="swiperChange" :style="{width:width+'rpx',height:height+'rpx'}">
  4. <swiper-item v-for="(item,index2) in list_data" :key="index2" :style="{width:width+'rpx',height:height+'rpx'}">
  5. <view
  6. v-if="(selectedWipeIndex==index2+1)||(selectedWipeIndex==index2-1)||selectedWipeIndex==index2" @scroll="scroll($event,index2)" :style="{width:width+'rpx',height:height+'rpx',overflowY:'auto'}">
  7. <view :style="{height:itemHeight_px*item.length+'px'
  8. }" :key="index2" class="relative">
  9. <view :style="{marginTop:sctop+'px'}" class="absolute fulled">
  10. <view :style="{height: '100rpx'}"
  11. v-for="(item,index) in chiledrenData.listData" :key="index"
  12. >
  13. <slot name="default" :itemdata="item">
  14. </slot>
  15. </view>
  16. </view>
  17. </view>
  18. </view>
  19. </swiper-item>
  20. </swiper>
  21. </view>
  22. </template>
  23. <script>
  24. export default {
  25. name:'tm-swiperList',
  26. props: {
  27. list:{
  28. type:Array,
  29. default:()=>[]
  30. },
  31. width:{
  32. type:Number,
  33. default:400
  34. },
  35. height:{
  36. type:Number,
  37. default:600
  38. },
  39. itemHeight:{
  40. type:Number,
  41. default:100
  42. }
  43. },
  44. data() {
  45. return {
  46. selectedWipeIndex:0,
  47. timed:96536,
  48. timed1:965361,
  49. showNum:0,//当前视图内可容纳的条数
  50. sctop:0,
  51. chiledrenData:{
  52. scroll:{
  53. showNum:6,//当前视图内可容纳的条数
  54. totalSum:40,//总条数
  55. topIndex:0,//顶部位置条目的索引
  56. preateIndex:0,
  57. top:0
  58. },
  59. listData:[]//列表可以渲染的数据。
  60. }
  61. };
  62. },
  63. watch:{
  64. list:{
  65. deep:true,
  66. handler(){
  67. this.setDefault();
  68. }
  69. }
  70. },
  71. computed: {
  72. showSlotData:function () {
  73. console.log(this.chiledrenData);
  74. return JSON.stringify(this.chiledrenData)
  75. },
  76. itemHeight_px:function () {
  77. return uni.upx2px(this.itemHeight)
  78. },
  79. list_data:function () {
  80. return this.list;
  81. },
  82. total_rx() {
  83. return this.total;
  84. }
  85. },
  86. mounted(){
  87. },
  88. created(){
  89. //计算当前视图内可容纳的条数
  90. this.showNum = Math.floor(uni.upx2px(this.height)/uni.upx2px(this.itemHeight));
  91. },
  92. methods: {
  93. swiperChange(e){
  94. let t =this;
  95. clearTimeout(this.timed)
  96. this.timed = setTimeout(function() {
  97. t.selectedWipeIndex = e.detail.current;
  98. }, 50);
  99. },
  100. scroll(e){
  101. let t = this;
  102. let sp = Math.floor(parseInt(e.detail.scrollTop));
  103. this.sctop = e.detail.scrollTop
  104. let to = Math.floor(parseInt(e.detail.scrollHeight));
  105. //计算总的条数。
  106. let totalSum = Math.floor(to / uni.upx2px(this.itemHeight));
  107. //计算当前top位置的index.
  108. let topIndex= Math.floor(sp/uni.upx2px(this.itemHeight));
  109. topIndex = topIndex-1;
  110. topIndex = topIndex<=0?0:topIndex;
  111. //当前视图内可容纳的条数
  112. let nowViewBoxnum = this.showNum;
  113. let chiledrenData = {
  114. scroll:{
  115. showNum:nowViewBoxnum,//当前视图内可容纳的条数
  116. totalSum:totalSum,//总条数
  117. topIndex:topIndex,//顶部位置条目的索引
  118. top:sp,
  119. }
  120. }
  121. clearTimeout(this.timed1)
  122. this.timed1 = setTimeout(function() {
  123. t.setDefault(chiledrenData,e.detail.deltaY)
  124. }, 50);
  125. },
  126. setDefault(chiledrenData,dy){
  127. let t = this;
  128. if(this.list.length==0) return;
  129. if(!Array.isArray(this.list[this.selectedWipeIndex])) return;
  130. if(this.list[this.selectedWipeIndex].length==0) return;
  131. if(!chiledrenData) chiledrenData = this.chiledrenData;
  132. //计算当前显示的条数。
  133. let p = this.list[this.selectedWipeIndex];
  134. let start = chiledrenData.scroll.topIndex;
  135. let end = start+this.showNum
  136. let d_endIndex = chiledrenData.scroll.topIndex%this.showNum;
  137. let s = chiledrenData.scroll.topIndex
  138. let e = s+(this.showNum-d_endIndex);
  139. let sholist = p.slice(s,e);
  140. //补齐的数据。
  141. let bu = p.slice(e,e+d_endIndex)
  142. let oslist = [...sholist,...bu];
  143. oslist = oslist.map((el,index)=>{
  144. console.log(chiledrenData.scroll.top,chiledrenData.scroll.top+index*t.itemHeight_px);
  145. return {src:el,top:chiledrenData.scroll.top+index*t.itemHeight_px};
  146. })
  147. this.chiledrenData = {
  148. scroll:{...chiledrenData.scroll,preateIndex:this.selectedWipeIndex},
  149. listData:oslist
  150. }
  151. },
  152. findChildren(){
  153. let t = this;
  154. let box = [];
  155. function findchild(p,index){
  156. let preat = p;
  157. if(preat.$options?.name==='tm-swiperListItem'){
  158. preat.test.call(preat,t.index)
  159. }else{
  160. if(preat.$children.length>0){
  161. preat.$children.forEach(item=>{
  162. findchild(item,index++);
  163. })
  164. }
  165. }
  166. };
  167. findchild(this.$children[0],0);
  168. },
  169. },
  170. }
  171. </script>
  172. <style lang="scss">
  173. </style>