index-list.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <view class="container">
  3. <!-- <view class="indexPosition">
  4. <view class="activeKey" v-for="(item,index) in keyList" @click="activeKeyHandle(item)">{{item}}
  5. </view>
  6. </view> -->
  7. <scroll-view scroll-y="true" class="scroll-Y" :scroll-top="top" scroll-with-animation="true" @scroll="scroll">
  8. <view :class="[`box ${item.letter}`]" v-for="item in options">
  9. <view class="letter">{{item.letter}}</view>
  10. <view class="listWrap">
  11. <view class="list" v-for="val in item.data" @click="listClickHandle(val)">
  12. <view :class="[isSelectAll||checkedListIds.includes(val.id)?'iconWrap':'iconWrap on']">
  13. <image v-if="isSelectAll||checkedListIds.includes(val.id)" class="checkedIcon"
  14. src="../../static/check-checkbox.png" mode=""></image>
  15. </view>
  16. <text class="mainText">{{val.main}}</text>
  17. <text class="subText">{{val.sub}}</text>
  18. </view>
  19. </view>
  20. </view>
  21. </scroll-view>
  22. </view>
  23. </template>
  24. <script>
  25. export default {
  26. name: "index-list",
  27. props: {
  28. checkedResponsibleList: Array,
  29. options: Array,
  30. },
  31. data() {
  32. return {
  33. checkedList: [],
  34. checkedListIds: [],
  35. isSelectAll: false,
  36. keyList: [
  37. 'A', 'B', 'C', 'D'
  38. ],
  39. top:0
  40. };
  41. },
  42. computed: {
  43. },
  44. watch: {
  45. checkedResponsibleList: function(newVal, oldVal) {
  46. // console.log({newVal,oldVal});
  47. if (newVal.length != oldVal.length) {
  48. this.checkedListIds = JSON.parse(JSON.stringify(newVal)).map(item => item.id);
  49. this.checkedList = JSON.parse(JSON.stringify(newVal));
  50. this.$emit("listClick", this.checkedList);
  51. }
  52. },
  53. options:function(){
  54. this.checkedList=[];
  55. this.checkedListIds = JSON.parse(JSON.stringify(this.checkedResponsibleList)).map(item => item.id);
  56. this.checkedList = JSON.parse(JSON.stringify(this.checkedResponsibleList));
  57. }
  58. },
  59. mounted() {
  60. this.checkedListIds = JSON.parse(JSON.stringify(this.checkedResponsibleList)).map(item => item.id);
  61. this.checkedList = JSON.parse(JSON.stringify(this.checkedResponsibleList));
  62. // console.log(this.checkedListIds);
  63. },
  64. methods: {
  65. scroll(event){
  66. const {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY} = event.detail;
  67. console.log({scrollTop});
  68. },
  69. activeKeyHandle(key) {
  70. this.getDescBox(`.${key.toLowerCase()}`).then(res=>{
  71. console.log({res});
  72. console.log(`.${key.toLowerCase()}`);
  73. if(!res||res-80<=0||res == this.top-80)return;
  74. this.top = res-80;
  75. // let timer = setInterval(()=>{
  76. // this.top = this.top + 500;
  77. // if(this.top >=res-100 ){
  78. // clearInterval(timer);
  79. // }
  80. // },60);
  81. // uni.pageScrollTo({
  82. // duration:500, // 毫秒
  83. // scrollTop:100, // 位置
  84. // complete:()=>{
  85. // console.log('done');
  86. // }
  87. // });
  88. });
  89. },
  90. // 获取元素距离顶部的高度
  91. getDescBox(className) {
  92. let that = this;
  93. let count = 0;
  94. return new Promise(resolve => {
  95. getHeight();
  96. function getHeight() {
  97. uni
  98. .createSelectorQuery()
  99. .in(that)
  100. .select(className)
  101. .boundingClientRect()
  102. .exec(res => {
  103. if (res[0]) {
  104. resolve(res[0].top);
  105. } else {
  106. that.$nextTick(() => {
  107. ++count <= 8 ? getHeight() : resolve(null);
  108. });
  109. }
  110. });
  111. }
  112. });
  113. },
  114. listClickHandle(val) {
  115. const tempIdsArr = JSON.parse(JSON.stringify(this.checkedListIds));
  116. const tempArr = JSON.parse(JSON.stringify(this.checkedList));
  117. const data = JSON.parse(JSON.stringify(val));
  118. // console.log({tempIdsArr,tempArr});
  119. // console.log(tempIdsArr.includes(data.id));
  120. if (tempIdsArr.includes(data.id)) {
  121. this.isSelectAll = false;
  122. tempIdsArr.splice(tempIdsArr.indexOf(data.id), 1);
  123. this.checkedList = tempArr.filter(item => item.id != data.id);
  124. this.checkedListIds = tempIdsArr;
  125. } else {
  126. this.checkedList.push(data);
  127. this.checkedListIds.push(data.id);
  128. // console.log(this.checkedListIds);
  129. }
  130. this.$emit("listClick", this.checkedList);
  131. }
  132. }
  133. }
  134. </script>
  135. <style lang="less">
  136. .container {
  137. position: relative;
  138. z-index: 1;
  139. height: 100%;
  140. overflow: scroll;
  141. .indexPosition {
  142. display: flex;
  143. flex-direction: column;
  144. justify-content: center;
  145. align-items: center;
  146. position: absolute;
  147. z-index: 10;
  148. right: 0;
  149. width: 50rpx;
  150. height: 100%;
  151. background-color: red;
  152. .activeKey {
  153. display: flex;
  154. justify-content: center;
  155. align-items: center;
  156. flex: 1;
  157. width: 100%;
  158. }
  159. }
  160. .scroll-Y {
  161. height: 100%;
  162. .box {
  163. .letter {
  164. height: 62.5rpx;
  165. line-height: 62.5rpx;
  166. font-size: 22.5rpx;
  167. font-family: SourceHanSansCN-Normal, SourceHanSansCN;
  168. font-weight: 400;
  169. color: #666F80;
  170. padding: 0 25rpx;
  171. }
  172. .listWrap {
  173. background-color: #FFFFFF;
  174. .list {
  175. position: relative;
  176. display: flex;
  177. flex-direction: row;
  178. justify-content: flex-start;
  179. align-items: center;
  180. height: 87.5rpx;
  181. padding: 0 25rpx;
  182. .iconWrap {
  183. width: 25rpx;
  184. height: 25rpx;
  185. margin-right: 25rpx;
  186. .checkedIcon {
  187. width: 25rpx;
  188. height: 25rpx;
  189. }
  190. &.on {
  191. border-radius: 50%;
  192. border: 2.5rpx solid #C3CAD9;
  193. }
  194. }
  195. .mainText {
  196. display: inline-block;
  197. font-size: 22.5rpx;
  198. font-family: SourceHanSansCN-Normal, SourceHanSansCN;
  199. font-weight: 400;
  200. color: #292C33;
  201. margin-right: 50rpx;
  202. }
  203. .subText {
  204. font-size: 22.5rpx;
  205. font-family: SourceHanSansCN-Normal, SourceHanSansCN;
  206. font-weight: 400;
  207. color: #7A8499;
  208. }
  209. &::after {
  210. position: absolute;
  211. right: 0;
  212. bottom: 0;
  213. display: block;
  214. content: '';
  215. width: 90%;
  216. border-bottom: 1px solid #DADEE6;
  217. }
  218. &:last-child {
  219. &::after {
  220. display: none;
  221. }
  222. }
  223. }
  224. }
  225. }
  226. }
  227. }
  228. </style>