filtrate.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <view class="filtrate-box">
  3. <view :style="{ position: 'absolute', zIndex: index }">
  4. <u-transition :show="show">
  5. <view class="shade" catchtouchmove="true" @touchmove.stop.prevent="() => { }" @click="changeShow">
  6. <view @click.stop="">
  7. <scroll-view :style="{ maxHeight: tovw(maxHeight) }" class="scroll-view" scroll-y>
  8. <group v-for="(item, index) in list" :ref="'group' + index" :key="item.key" :item="item"
  9. :rowIndex="index" @onChange="onChange" />
  10. </scroll-view>
  11. <view class="but-box">
  12. <view class="reset" hover-class="navigator-hover" @click="onReset">
  13. 重置
  14. </view>
  15. <view class="confirm" hover-class="navigator-hover" @click="onConfirm">
  16. 确定
  17. </view>
  18. </view>
  19. </view>
  20. </view>
  21. </u-transition>
  22. </view>
  23. </view>
  24. </template>
  25. <script>
  26. import group from "./filtrate-group.vue"
  27. export default {
  28. components: { group },
  29. props: {
  30. zIndex: {
  31. type: [String, Number],
  32. default: 9
  33. },
  34. filtrateList: {
  35. type: Array,
  36. default: [{
  37. title: "",//组名称
  38. key: 'id',//提交时返回的Key
  39. showKey: "",//显示的key
  40. selected: "",//选择时选择的字段
  41. isAll: false,//true 返回整个对象 false 返回selected选中的value
  42. value: "",//提交时选中的value
  43. defaultVal: "",//默认值
  44. rang: "",//选择的范围
  45. interrupt: false,//中断
  46. }]
  47. },
  48. arrName: {
  49. type: String,
  50. default: "filtrateList"
  51. },
  52. onFiltration: {
  53. type: Function
  54. },
  55. onInterrupt: {
  56. type: Function
  57. }
  58. },
  59. watch: {
  60. filtrateList: function (newVal) {
  61. if (newVal) {
  62. this.list = JSON.parse(JSON.stringify(newVal))
  63. } else {
  64. }
  65. }
  66. },
  67. data() {
  68. return {
  69. show: false,
  70. maxHeight: 0,
  71. index: -99,
  72. list: []
  73. }
  74. },
  75. methods: {
  76. changeShow() {
  77. this.show = !this.show;
  78. if (this.show) {
  79. this.index = this.zIndex
  80. setTimeout(this.setHeight, 10);
  81. } else {
  82. setTimeout(() => { this.index = -99 }, 150)
  83. }
  84. },
  85. setHeight() {
  86. this.getHeight(".filtrate-box", this).then(res => {
  87. this.maxHeight = res - 300;
  88. });
  89. },
  90. onChange(option, index) {
  91. let item = this.list[index];
  92. this.$set(item, 'value', option[item.selected]);
  93. try {
  94. if (item.isAll) item.selectObj = option;
  95. } catch (error) { }
  96. this.$set(this.list, index, item);
  97. if (item.interrupt) this.$emit("onInterrupt", { item, index, option })
  98. },
  99. onReset() {
  100. let page = getCurrentPages()[getCurrentPages().length - 1];
  101. // #ifdef H5
  102. this.list = JSON.parse(JSON.stringify(page[this.arrName]))
  103. // #endif
  104. // #ifndef H5
  105. this.list = JSON.parse(JSON.stringify(page.data[this.arrName]))
  106. // #endif
  107. },
  108. onConfirm() {
  109. let obj = {};
  110. this.list.forEach(v => {
  111. if (v.value || v.defaultVal) {
  112. if (v.isAll) {
  113. obj[v.key] = v.rang.find(s => s[v.selected] == v.value) || v.rang.find(s => s[v.selected] == v.defaultVal);
  114. } else {
  115. obj[v.key] = v.value || v.defaultVal;
  116. }
  117. } else {
  118. obj[v.key] = v.rang.find(s => s[v.selected] == v.value || s[v.selected] == v.defaultVal);
  119. }
  120. })
  121. this.$emit("onFiltration", obj)
  122. this.changeShow();
  123. },
  124. },
  125. }
  126. </script>
  127. <style lang="scss">
  128. .filtrate-box {
  129. position: relative;
  130. .scroll-view {
  131. width: 100vw;
  132. background: #fff;
  133. }
  134. .but-box {
  135. display: flex;
  136. justify-content: space-between;
  137. width: 100vw;
  138. padding: 10px;
  139. background: #fff;
  140. box-sizing: border-box;
  141. .reset {
  142. width: 82px;
  143. height: 45px;
  144. line-height: 45px;
  145. text-align: center;
  146. background: #FFFFFF;
  147. border-radius: 5px;
  148. border: 1px solid #999999;
  149. }
  150. .confirm {
  151. width: 263px;
  152. height: 45px;
  153. text-align: center;
  154. line-height: 45px;
  155. background: #C30D23;
  156. border-radius: 5px;
  157. font-size: 16px;
  158. color: #FFFFFF;
  159. }
  160. }
  161. .shade {
  162. position: absolute;
  163. top: 0;
  164. width: 100vw;
  165. height: 9999px;
  166. background: rgba($color: #000000, $alpha: .7);
  167. }
  168. }
  169. </style>