zhilin-picker.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <template>
  2. <view class="zhilin-picker">
  3. <uni-popup ref="popup" type="top" @change="popupChange">
  4. <uni-nav-bar @clickLeft="clickLeft" @clickRight="tapOK" rightText="确定" left-icon="closeempty" :title="title" :border="null"></uni-nav-bar>
  5. <view class="usb">
  6. <uni-search-bar v-if="showSearch" :radius="100" cancelButton="none" v-model="searchVal"></uni-search-bar>
  7. </view>
  8. <view class="main" v-if="list.length">
  9. <scroll-view scroll-y="true" @scrolltolower="lower" :lower-threshold="1">
  10. <view class="scroll-view-item flex" v-for="(v,i) in list" :key="i" @tap="tapItem(v.id,v.name,v)" :class="selected.indexOf(v.id)>-1?'selected':null">
  11. <view>
  12. <view>{{v.name}}</view>
  13. <text class="detail_address">{{v.province}}{{v.city}}{{v.district}}{{v.detail_address}}</text>
  14. </view>
  15. <view><icon v-show="selected.indexOf(v.id)>-1" type="success_no_circle" size="22" /></view>
  16. </view>
  17. <view v-if="showBottom" class="isBottom">已经到底啦~</view>
  18. </scroll-view>
  19. <view class="loadingBox" v-show="loading">
  20. <uni-load-more status="loading"></uni-load-more>
  21. </view>
  22. </view>
  23. <view v-else class="empty">
  24. <xw-empty text="暂无选项" textColor="#777777"></xw-empty>
  25. </view>
  26. </uni-popup>
  27. </view>
  28. </template>
  29. <script>
  30. import uniPopup from "../uni-popup/uni-popup.vue"
  31. import uniNavBar from "../uni-nav-bar/uni-nav-bar.vue"
  32. import xwEmpty from "../xw-empty/xw-empty.vue"
  33. import uniSearchBar from '../uni-search-bar/uni-search-bar.vue'
  34. import uniLoadMore from "../more/uni-load-more.vue"
  35. export default {
  36. name: 'zhilin-select',
  37. components: {
  38. uniPopup,
  39. uniNavBar,
  40. xwEmpty,
  41. uniSearchBar,
  42. uniLoadMore
  43. },
  44. props: {
  45. title: {
  46. type: String,
  47. default: '请选择'
  48. },
  49. value: {
  50. type: Boolean,
  51. required: true
  52. },
  53. data: {
  54. type: Array,
  55. required: true
  56. },
  57. multiple: {
  58. type: Boolean,
  59. default: false
  60. },
  61. showSearch: {
  62. type: Boolean,
  63. default: false
  64. },
  65. searchInput: Function,
  66. initSelected: Array
  67. },
  68. data() {
  69. return {
  70. list: [],
  71. selected: [],
  72. showBottom: false,
  73. loading: false,
  74. searchVal: ''
  75. }
  76. },
  77. created() {
  78. this.dataInit()
  79. },
  80. watch: {
  81. value(n, o) {
  82. if (n) this.$refs.popup.open()
  83. else this.$refs.popup.close()
  84. },
  85. data(n, o) {
  86. this.loading = false
  87. this.showBottom = false
  88. this.dataInit()
  89. },
  90. searchVal(){
  91. this.$emit("searchInput",this.searchVal)
  92. this.inputSearch()
  93. },
  94. initSelected(n){
  95. this.selected = n
  96. }
  97. },
  98. methods: {
  99. lower: function(e) {
  100. this.showBottom = true
  101. },
  102. dataInit() {
  103. this.list = this.data;
  104. },
  105. clickLeft() {
  106. this.$emit("input", false)
  107. },
  108. tapItem(val,name,v) {
  109. console.log(val,name,v)
  110. if (this.multiple) {
  111. let idx = this.selected.indexOf(val)
  112. if (idx == -1) {
  113. this.selected.push(val)
  114. } else {
  115. this.selected.splice(idx, 1)
  116. }
  117. } else {
  118. this.selected = [val,name,v.city,v.city_id,v.district,v.district_id,v.province,v.province_id,]
  119. }
  120. this.$emit("change", this.selected.join())
  121. },
  122. tapOK() {
  123. if(this.selected.join() == '' && this.list != ''){
  124. this.$api.msg('请先点击医院列表选择医院!');
  125. return;
  126. }
  127. this.$emit("input", false)
  128. this.$emit("confirm", this.selected.join())
  129. },
  130. popupChange(e) {
  131. this.$emit("input", e.show)
  132. },
  133. inputSearch() {
  134. let val = this.searchVal
  135. if(this.searchInput){
  136. this.loading = true
  137. this.searchInput(val)
  138. return
  139. }
  140. this.showBottom = false
  141. if(this.list == ''){
  142. }else{
  143. this.list = this.list.map((v, i) => ({
  144. label: v,
  145. value: v
  146. }))
  147. }
  148. }
  149. }
  150. }
  151. </script>
  152. <style lang="scss">
  153. .zhilin-picker {
  154. font-size: 28rpx;
  155. uni-popup /deep/ .uni-popup {
  156. width: 750rpx;
  157. background: #fff;
  158. height: 1056rpx;
  159. overflow: hidden;
  160. display: flex;
  161. flex-direction: column;
  162. }
  163. uni-popup {
  164. .usb {
  165. padding: 0 32rpx;
  166. background: #fff;
  167. }
  168. }
  169. }
  170. .main {
  171. height: calc(800rpx - 192rpx);
  172. flex: 1;
  173. position: relative;
  174. background: #fff;
  175. scroll-view {
  176. height: 100%;
  177. .scroll-view-item {
  178. box-sizing: border-box;
  179. padding: 18rpx 44rpx !important;
  180. display: flex;
  181. justify-content: space-between;
  182. align-items: center;
  183. min-height: 80rpx;
  184. &.selected {
  185. background:rgba(0, 122, 255, 0.1);
  186. }
  187. uni-text {
  188. width: 85%;
  189. }
  190. }
  191. .isBottom {
  192. display: flex;
  193. justify-content: center;
  194. color: #777;
  195. position: relative;
  196. padding: 18rpx 44rpx;
  197. font-size: 24rpx;
  198. &::after {
  199. content: '';
  200. position: absolute;
  201. bottom: 10rpx;
  202. width: 60rpx;
  203. height: 4rpx;
  204. left: 50%;
  205. transform: translateX(-51%);
  206. background: #777;
  207. }
  208. }
  209. }
  210. .loadingBox {
  211. height: 100%;
  212. width: 100%;
  213. position: absolute;
  214. top: 0;
  215. left: 0;
  216. background: rgba(255, 255, 255, .7);
  217. z-index: 2;
  218. uni-load-more {
  219. display: flex;
  220. justify-content: center;
  221. position: absolute;
  222. width: 100%;
  223. top: 35%;
  224. left: 50%;
  225. transform: translate(-50%);
  226. }
  227. }
  228. }
  229. .detail_address{
  230. color: #969696;
  231. font-size: 24rpx;
  232. padding-top: 10rpx;
  233. }
  234. .empty {
  235. background: #fff;
  236. }
  237. </style>