You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

u-dropdown-list.vue 5.8 KiB

пре 2 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <view class="dropdown-list-wapper u-flex u-flex-1">
  3. <view
  4. v-for="(drop, index) in dropdownListFromFather"
  5. :key="drop.name"
  6. :show="drop.show"
  7. class="u-selected-class u-dropdown-list"
  8. :style="{ zIndex: zIndex + 1 }"
  9. >
  10. <slot name="selectionbox">
  11. <view
  12. :style="{ height: top + 'rpx' }"
  13. class="drop-item u-flex u-justify-center"
  14. @click="handleDropClick(drop)"
  15. >
  16. <text :style="{ color: drop.show ? activeColor : '#999' }">
  17. {{ getTitle(drop.options) }}
  18. </text>
  19. <view
  20. class="u-animation"
  21. :class="[drop.show ? 'u-animation-show' : '']"
  22. >
  23. <u-icon
  24. v-if="drop.show"
  25. name="arrow-up-fill"
  26. :size="18"
  27. :color="activeColor"
  28. ></u-icon>
  29. <u-icon v-else name="arrow-down-fill" :size="18"></u-icon>
  30. </view>
  31. </view>
  32. </slot>
  33. <view
  34. class="u-dropdown-view"
  35. :class="[drop.show ? 'u-dropdownlist-show' : '']"
  36. :style="{
  37. background: bgcolor,
  38. height: drop.show ? 'auto' : 0,
  39. top: top + 'rpx'
  40. }"
  41. >
  42. <slot name="dropdownbox">
  43. <view class="u-selected-list">
  44. <view
  45. class="select-item u-flex u-align-center u-border-bottom u-align-between"
  46. :style="{ color: select.select ? activeColor : '#666666' }"
  47. @tap="handleSelected(select, drop.options)"
  48. v-for="(select, n) in drop.options"
  49. :key="n"
  50. >
  51. <text>{{ select.text }}</text>
  52. <u-icon
  53. v-if="select.select"
  54. class="select-icon"
  55. :color="activeColor"
  56. size="35"
  57. name="checkmark"
  58. ></u-icon>
  59. </view>
  60. </view>
  61. </slot>
  62. </view>
  63. </view>
  64. <u-mask
  65. duration="100"
  66. :show="dropdownShow"
  67. @click="closeMask"
  68. :z-index="zIndex"
  69. ></u-mask>
  70. </view>
  71. </template>
  72. <script>
  73. const dropdownOption1 = [
  74. { id: 0, text: '类型', value: '', select: false },
  75. { id: 1, text: '全场券', value: 1, select: false },
  76. { id: 2, text: '品类券', value: 2, select: false },
  77. { id: 3, text: '单品券', value: 3, select: false },
  78. { id: 4, text: '业务券', value: 4, select: false }
  79. ]
  80. const dropdownOption2 = [
  81. { id: 5, text: '状态', value: '', select: false },
  82. { id: 6, text: '可使用', value: 1, select: false },
  83. { id: 7, text: '已过期', value: 2, select: false }
  84. ]
  85. const dropdownOption3 = [
  86. { id: 8, text: '优惠力度', value: '', select: false },
  87. { id: 9, text: '满100-20', value: 1, select: false },
  88. { id: 10, text: '满100-50', value: 2, select: false }
  89. ]
  90. export default {
  91. props: {
  92. // 下拉框数据
  93. dropdownList: {
  94. type: Array,
  95. default: () => [
  96. { show: false, options: dropdownOption1 },
  97. { show: false, options: dropdownOption2 },
  98. { show: false, options: dropdownOption3 }
  99. ],
  100. required: true,
  101. validator: value =>
  102. value.every(item => Array.isArray(item.options) && item.options.length)
  103. },
  104. //背景颜色
  105. bgcolor: {
  106. type: String,
  107. default: 'none'
  108. },
  109. //top rpx 选择框高度也用这个值
  110. top: {
  111. type: Number,
  112. default: 90
  113. },
  114. // 菜单标题和选项的选中态颜色
  115. activeColor: {
  116. type: String,
  117. default: '#e7141a'
  118. },
  119. // mask和下拉列表的z-index
  120. zIndex: {
  121. type: [String, Number],
  122. default: 21
  123. }
  124. },
  125. data() {
  126. return {
  127. dropdownShow: false,
  128. dropdownListFromFather: this.dropdownList
  129. }
  130. },
  131. computed: {},
  132. methods: {
  133. getTitle(item = []) {
  134. const obj = item.find(v => v.select) || {}
  135. if (obj.select) {
  136. return obj.text
  137. } else {
  138. if (item[0]) {
  139. item[0].select = true
  140. return item[0].text
  141. }
  142. }
  143. return ''
  144. },
  145. handleDropClick(item) {
  146. if (item.show) {
  147. item.show = false
  148. this.dropdownShow = false
  149. return
  150. }
  151. this.dropdownListFromFather.map(item => {
  152. item.show = false
  153. })
  154. const t = setTimeout(() => {
  155. item.show = true
  156. this.dropdownShow = true
  157. clearTimeout(t)
  158. }, 100)
  159. },
  160. closeMask() {
  161. this.dropdownShow = false
  162. this.dropdownListFromFather.map(item => {
  163. item.show = false
  164. })
  165. },
  166. handleSelected(select, options) {
  167. options.map(item => {
  168. item.select = false
  169. })
  170. select.select = true
  171. this.closeMask()
  172. // 返回选中对象和下拉列表数组
  173. this.$emit('change', select, options)
  174. }
  175. },
  176. watch: {
  177. dropdownList: {
  178. handler(v) {
  179. this.dropdownListFromFather = v
  180. },
  181. deep: true
  182. }
  183. }
  184. }
  185. </script>
  186. <style lang="scss" scoped>
  187. @import "../../libs/css/style.components.scss";
  188. .dropdown-list-wapper {
  189. position: relative;
  190. }
  191. .u-dropdown-view {
  192. width: 100%;
  193. overflow: hidden;
  194. position: absolute;
  195. z-index: 9999;
  196. left: 0;
  197. right: 0;
  198. /* opacity: 0; */
  199. visibility: hidden;
  200. transition: height 0.5s ease-in-out;
  201. .u-selected-list {
  202. background-color: #fff;
  203. .select-item {
  204. color: #666666;
  205. font-size: 28rpx;
  206. padding: 30rpx 54rpx 30rpx 30rpx;
  207. margin-left: 30rpx;
  208. }
  209. .select-item.selectActive {
  210. color: #e7141a;
  211. }
  212. }
  213. }
  214. .u-dropdownlist-show {
  215. /* opacity: 1; */
  216. visibility: visible;
  217. }
  218. .u-dropdown-list {
  219. flex: 1;
  220. // z-index: 22;
  221. background: #fff;
  222. position: static;
  223. }
  224. .drop-item {
  225. justify-content: center;
  226. color: #999999;
  227. font-size: 30rpx;
  228. > text {
  229. margin-right: 10rpx;
  230. }
  231. /deep/ {
  232. .uicon {
  233. position: relative;
  234. top: -2rpx;
  235. }
  236. }
  237. }
  238. </style>