jPicker.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <template>
  2. <view class="jPicker">
  3. <view @click="showPicker" class="showLine">
  4. <view v-if="listData.length>0&&nSel!=-1">
  5. {{listData[nSel][showKey]||listData[nSel]}}
  6. </view>
  7. <view style="color:#7d7d7d;" v-else>
  8. 请选择小区
  9. </view>
  10. </view>
  11. <view class="pickerMask" v-if="pickerVisable" @click="pickerVisable=false">
  12. <view class="alertArea JAnimateBtmIn" @click.stop="doNothing">
  13. <view class="searchInput " v-if="searchPosition=='top'">
  14. <view class="clickArea">
  15. <input class="jInput" placeholder-style="color:#ffffff" @input="filterOp" placeholder="搜索小区名称..." />
  16. <!-- <image class="searchLogo" src="../../static/search.png"></image> -->
  17. <icon class="searchLogo" type="search" />
  18. </view>
  19. </view>
  20. <view class="pickerTop">
  21. <view class="lefBtn" @click="cancelSel">取消</view>
  22. <view class="midInput">
  23. <template v-if="searchPosition=='middle'">
  24. <input class="searchArea" @input="filterOp" />
  25. <!-- <image class="searchIcon" src="../../static/search.png"></image> -->
  26. <icon class="searchIcon" type="search" />
  27. </template>
  28. </view>
  29. <view class="rigBtn" :style="{color:sureColor}" @click="sureSelect">确定</view>
  30. </view>
  31. <picker-view :value="[nSel]" class="pickerView" :mask-style="'background-color:'+bgColor" :indicator-style="selStyle" @change="selChange">
  32. <picker-view-column>
  33. <view class="opItem" v-for="(item,index) in listData" :key="index">{{item[showKey]||item}}</view>
  34. </picker-view-column>
  35. </picker-view>
  36. </view>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. /**
  42. * 选择组件
  43. * @property {Array} options 选择数组
  44. * @property {String} showKey 显示的对象键名
  45. * @property {String} val 默认选中下标
  46. * @property {String} valKey 取值的对象键名
  47. * @property {Boolean} disabled 是否只读
  48. * @event {Function} position 搜索框位置
  49. * @event {Function} sure 确认事件
  50. * @example <jPicker :disabled="false" class="cont" @sure="bindPickerChange($event,'TYPE')" showKey="Name" valKey="Value" :val="CurrentType" :options="FilterArray" />
  51. */
  52. export default {
  53. name: 'jPicker',
  54. data() {
  55. return {
  56. listData: this.options,
  57. nSel: -1,
  58. pickerVisable: true,
  59. searchPosition: "middle",
  60. //picker样式
  61. // unSelStyle:'',
  62. //'background-color:rgba(0, 74, 255, 0.44);',//'background-color:rgba(220, 250, 9, 0.44);',rgba(250, 9, 9, 0.44)
  63. selStyle: 'height:50px;',
  64. }
  65. },
  66. props: ["options", "showKey", "valKey", "val", "position", "disabled", "bgColor", "sureColor"],
  67. //选项数组,列表显示的对象键名,取值的对象键名,默认选中值,搜索框位置,是否禁用,整体背景色,确认键颜色
  68. watch: {
  69. options(n) {
  70. this.listData = n;
  71. this.selByValKey();
  72. },
  73. val(n) {
  74. this.selByValKey();
  75. },
  76. },
  77. mounted() {
  78. this.selByValKey();
  79. if (this.position) {
  80. this.searchPosition = this.position;
  81. }
  82. },
  83. methods: {
  84. showPicker() {
  85. if (this.disabled) {
  86. return;
  87. }
  88. this.pickerVisable = true;
  89. this.listData = this.options;
  90. },
  91. cancelSel() {
  92. this.pickerVisable = false;
  93. /*
  94. if (this.val) {
  95. if (this.valKey) {
  96. let n = this.listData;
  97. for (let j = 0, len = n.length; j < len; j++) {
  98. if (n[j][this.valKey] == this.val) {
  99. this.nSel = j;
  100. break;
  101. }
  102. }
  103. } else {
  104. this.nSel = this.val;
  105. }
  106. } else {
  107. this.nSel = -1;
  108. }
  109. */
  110. },
  111. sureSelect() {
  112. this.pickerVisable = false;
  113. if (this.listData.length == 0) {
  114. // uni.showToast({
  115. // title:"未选中"
  116. // })
  117. this.$emit("sure", {});
  118. } else {
  119. let obj = {
  120. pickerVal: this.nSel,
  121. pickerName: this.nSel == -1 ? this.listData[0] : this.listData[this.nSel],
  122. };
  123. if (this.valKey) {
  124. // obj=this.nSel == -1?this.listData[0]:this.listData[this.nSel];
  125. // obj.pickerVal = obj[this.valKey];//2020-01-10
  126. if (this.nSel != -1) {
  127. obj = this.listData[this.nSel];
  128. obj.pickerVal = obj[this.valKey];
  129. } else {
  130. //obj.pickerVal=-1;
  131. obj = this.listData[0]
  132. obj.pickerVal = obj[this.valKey];
  133. }
  134. }
  135. this.$emit("sure", obj);
  136. }
  137. },
  138. selChange(e) {
  139. this.nSel = e.detail.value[0];
  140. },
  141. filterOp(e) {
  142. //console.log(e.detail.value);
  143. let keyWord = e.detail.value;
  144. if (keyWord != "") {
  145. keyWord = keyWord.toLowerCase();
  146. let oldArr = this.options;
  147. this.listData = [];
  148. this.nSel = 0;
  149. for (let i = 0; i < oldArr.length; i++) {
  150. let theVal = oldArr[i];
  151. if (this.showKey) {
  152. theVal = oldArr[i][this.showKey];
  153. }
  154. if (theVal.toString().toLowerCase().indexOf(keyWord) > -1) {
  155. this.listData.push(oldArr[i]);
  156. }
  157. }
  158. } else {
  159. this.listData = this.options;
  160. this.nSel = this.val ? this.val : -1;
  161. this.selByValKey();
  162. }
  163. },
  164. selByValKey() {
  165. let n = this.options;
  166. this.listData = n;
  167. if (this.valKey) { //看看指定了选中值的键名否,没有则默认为数据源index
  168. for (let j = 0, len = n.length; j < len; j++) {
  169. if (n[j][this.valKey] == this.val) {
  170. this.nSel = j;
  171. break;
  172. }
  173. }
  174. } else {
  175. this.nSel = this.val;
  176. }
  177. },
  178. doNothing() {
  179. //nothing
  180. },
  181. }
  182. }
  183. </script>
  184. <style lang="scss" scoped>
  185. .jPicker {
  186. width: 100%;
  187. .showLine {
  188. // border-left:1px solid #000000;
  189. width: 100%;
  190. display: inline-block;
  191. }
  192. }
  193. .pickerMask {
  194. background-color: rgba(0, 0, 0, 0.5);
  195. height: 100vh;
  196. width: 100vw;
  197. position: fixed;
  198. left: 0;
  199. top: 0;
  200. z-index: 999;
  201. }
  202. .alertArea {
  203. position: fixed;
  204. bottom: 0;
  205. left: 0;
  206. width: 100vw;
  207. // border-radius: 10px 10px 0 0;
  208. .searchInput {
  209. width: 100%;
  210. position: relative;
  211. .clickArea {
  212. width: 100%;
  213. display: flex;
  214. align-items: center;
  215. justify-content: center;
  216. height: 36px;
  217. .jInput {
  218. text-align: left;
  219. width: 90%;
  220. border: none;
  221. height: 30px;
  222. font-size: 17px;
  223. // border-radius: 20px;
  224. padding: 2px 8px;
  225. box-sizing: border-box;
  226. // background-color: #efefef;
  227. color: #ffffff;
  228. }
  229. .searchLogo {
  230. width: 30px;
  231. height: 30px;
  232. line-height: 30px;
  233. text-align: center;
  234. }
  235. }
  236. &:before {
  237. content: "";
  238. position: absolute;
  239. top: 0;
  240. left: 0;
  241. width: 100%;
  242. height: 100%;
  243. background: #678699;
  244. filter: blur(18px);
  245. z-index: -1;
  246. }
  247. }
  248. .pickerTop {
  249. background-color: #FFFFFF;
  250. height: 52px;
  251. display: flex;
  252. align-items: center;
  253. border-bottom: 1px solid #000000;
  254. font-size: 18px;
  255. box-sizing: border-box;
  256. justify-content: space-around;
  257. .lefBtn,
  258. .rigBtn {
  259. // display: inline-block;
  260. // vertical-align: top;
  261. font-size: 18px;
  262. // width: 18%;
  263. line-height: 1rem;
  264. // text-align: center;
  265. // padding: 5px 0;
  266. // height: 1.4em;
  267. }
  268. .rigBtn {
  269. color: #31C231;
  270. }
  271. .midInput {
  272. width: 64%;
  273. height: 30px;
  274. position: relative;
  275. line-height: 30px;
  276. // display: flex;
  277. // align-items: center;
  278. // justify-content: center;
  279. .searchArea {
  280. text-align: left;
  281. background-color: #efefef;
  282. border-radius: 20px;
  283. padding: 4px 10px;
  284. }
  285. .searchIcon {
  286. position: absolute;
  287. right: 5px;
  288. top: 0px;
  289. width: 30px;
  290. height: 30px;
  291. text-align: center;
  292. display: flex;
  293. align-items: center;
  294. }
  295. }
  296. }
  297. .pickerView {
  298. background-color: #FFFFFF;
  299. width: 100%;
  300. height: 300px;
  301. // margin-top:20upx;
  302. left: 0;
  303. .opItem {
  304. line-height: 50px;
  305. text-align: center;
  306. background-color: #f3f3f3;
  307. color: #000000;
  308. }
  309. }
  310. }
  311. .JAnimateBtmIn {
  312. animation: btmIn 0.3s ease;
  313. }
  314. @keyframes btmIn {
  315. 0%{
  316. transform: translateY(666px);
  317. }
  318. 100% {
  319. transform: translateY(0);
  320. }
  321. }
  322. </style>