zhilin-picker.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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(333,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. this.selected = [val,name]
  120. // this.selected = [name]
  121. }
  122. this.$emit("change", this.selected.join())
  123. },
  124. tapOK() {
  125. if(this.selected.join() == '' && this.list != ''){
  126. this.$api.msg('请先点击机构列表选择机构!');
  127. return;
  128. }
  129. this.$emit("input", false)
  130. this.$emit("confirm", this.selected.join())
  131. },
  132. popupChange(e) {
  133. this.$emit("input", e.show)
  134. },
  135. inputSearch() {
  136. let val = this.searchVal
  137. if(this.searchInput){
  138. this.loading = true
  139. this.searchInput(val)
  140. return
  141. }
  142. this.showBottom = false
  143. if(this.list == ''){
  144. }else{
  145. this.list = this.list.map((v, i) => ({
  146. label: v,
  147. value: v
  148. }))
  149. }
  150. }
  151. }
  152. }
  153. </script>
  154. <style lang="scss">
  155. .zhilin-picker {
  156. font-size: 28rpx;
  157. uni-popup /deep/ .uni-popup {
  158. width: 750rpx;
  159. background: #fff;
  160. height: 1056rpx;
  161. overflow: hidden;
  162. display: flex;
  163. flex-direction: column;
  164. }
  165. uni-popup {
  166. .usb {
  167. padding: 0 32rpx;
  168. background: #fff;
  169. }
  170. }
  171. }
  172. .main {
  173. height: calc(800rpx - 192rpx);
  174. flex: 1;
  175. position: relative;
  176. background: #fff;
  177. scroll-view {
  178. height: 100%;
  179. .scroll-view-item {
  180. box-sizing: border-box;
  181. padding: 18rpx 44rpx !important;
  182. display: flex;
  183. justify-content: space-between;
  184. align-items: center;
  185. min-height: 80rpx;
  186. &.selected {
  187. background:rgba(0, 122, 255, 0.1);
  188. }
  189. uni-text {
  190. width: 85%;
  191. }
  192. }
  193. .isBottom {
  194. display: flex;
  195. justify-content: center;
  196. color: #777;
  197. position: relative;
  198. padding: 18rpx 44rpx;
  199. font-size: 24rpx;
  200. &::after {
  201. content: '';
  202. position: absolute;
  203. bottom: 10rpx;
  204. width: 60rpx;
  205. height: 4rpx;
  206. left: 50%;
  207. transform: translateX(-51%);
  208. background: #777;
  209. }
  210. }
  211. }
  212. .loadingBox {
  213. height: 100%;
  214. width: 100%;
  215. position: absolute;
  216. top: 0;
  217. left: 0;
  218. background: rgba(255, 255, 255, .7);
  219. z-index: 2;
  220. uni-load-more {
  221. display: flex;
  222. justify-content: center;
  223. position: absolute;
  224. width: 100%;
  225. top: 35%;
  226. left: 50%;
  227. transform: translate(-50%);
  228. }
  229. }
  230. }
  231. .detail_address{
  232. color: #969696;
  233. font-size: 24rpx;
  234. padding-top: 10rpx;
  235. }
  236. .empty {
  237. background: #fff;
  238. }
  239. </style>