lin-select.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <template>
  2. <view class="yealuo-select">
  3. <view class="yealuo-background" @tap="isShow = false" v-show="isShow"></view>
  4. <view class="yealuo-con" :style="inputStyle" @tap='isShow = !isShow'>
  5. <slot name='left'></slot>
  6. <input class="uni-combox__input" :disabled="disabled" :placeholder="placeholder" v-model="theValue" @input="theInput" @focus="theFocus" @blur="theBlur" autocomplete="off" />
  7. <slot name='right' v-if="selectIco">
  8. <svg class="icon" v-if="!isShow" style="width: 1.5em; height: 1.5em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="530">
  9. <path d="M512 714.666667c-8.533333 0-17.066667-2.133333-23.466667-8.533334l-341.333333-341.333333c-12.8-12.8-12.8-32 0-44.8 12.8-12.8 32-12.8 44.8 0l320 317.866667 317.866667-320c12.8-12.8 32-12.8 44.8 0 12.8 12.8 12.8 32 0 44.8L533.333333 704c-4.266667 8.533333-12.8 10.666667-21.333333 10.666667z" p-id="531"></path>
  10. </svg>
  11. <svg class="icon" v-else style="width: 1.5em; height: 1.5em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1927">
  12. <path d="M904.533333 674.133333l-362.666666-362.666666c-17.066667-17.066667-42.666667-17.066667-59.733334 0l-362.666666 362.666666c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733333 0L512 401.066667l332.8 332.8c8.533333 8.533333 19.2 12.8 29.866667 12.8s21.333333-4.266667 29.866666-12.8c17.066667-17.066667 17.066667-42.666667 0-59.733334z" p-id="1928"></path>
  13. </svg>
  14. </slot>
  15. </view>
  16. <view class="uni-select__selector" v-show="show" :style="selectStyle">
  17. <view class="uni-popper__arrow"></view>
  18. <scroll-view scroll-y="true" class="uni-select__selector-scroll">
  19. <view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
  20. <text>{{emptyTips}}</text>
  21. </view>
  22. <view class="data">
  23. <radio-group v-if="checkType=='radio'" @change="selectCheckbox">
  24. <view class="select-item" :class="'item-'+overflow" v-for="(item, index) in nowData" :key="index">
  25. <label class="item-text" :class="{active: theValue==item.value}">
  26. <radio name="name1" checked v-if="theValue==item.value" :value="item.id">
  27. </radio>
  28. <radio name="name1" v-else :value="item.id"></radio>
  29. <text class="select-text">{{item.value}}</text>
  30. </label>
  31. </view>
  32. </radio-group>
  33. <checkbox-group v-else-if="checkType=='checkbox'" @change="selectCheckbox">
  34. <view class="select-item" :class="'item-'+overflow" v-for="(item, index) in nowData" :key="index">
  35. <label class="item-text" :class="{active: theValue.indexOf(item.value)!=-1 }">
  36. <checkbox name="name1" checked v-if="theValue.indexOf(item.value)!=-1 " :value="item.id"></checkbox>
  37. <checkbox name="name1" v-else :value="item.id"></checkbox>
  38. <text class="select-text">{{item.value}}</text>
  39. </label>
  40. </view>
  41. </checkbox-group>
  42. <radio-group v-else @change="selectCheckbox">
  43. <view class="select-item" :class="'item-'+overflow" v-for="(item, index) in nowData" :key="index">
  44. <label class="item-text" :class="{active: theValue==item.value}">
  45. <radio name="name1" style="display: none;" checked v-if="theValue==item.value" :value="item.id"></radio>
  46. <radio name="name1" style="display: none;" v-else :value="item.id">
  47. </radio>
  48. <text class="select-text">{{item.value}}</text>
  49. </label>
  50. </view>
  51. </radio-group>
  52. </view>
  53. </scroll-view>
  54. <view class="item-close" @tap="isShow=false">收起</view>
  55. </view>
  56. </view>
  57. </template>
  58. <script>
  59. /**
  60. * v1.0.3
  61. * 最后修改: 2023.03.24
  62. * 创建: 2023.03.24
  63. * Author: 林维增
  64. * contact:2630208719.com
  65. */
  66. let fontUnit = 'upx'
  67. // #ifdef MP-WEIXIN
  68. fontUnit = 'rpx'
  69. // #endif
  70. export default {
  71. name: 'yealuoInputs',
  72. props: {
  73. placeholder: {
  74. type: String,
  75. default: ''
  76. },
  77. //初始化
  78. value: {
  79. type: String,
  80. default: ''
  81. },
  82. checkType: {
  83. type: String,
  84. default: ''
  85. },
  86. itemKey: {
  87. type: String,
  88. default: ''
  89. },
  90. width: {
  91. type: String,
  92. default: '600'
  93. },
  94. disabled: {
  95. type: Boolean,
  96. default: false
  97. },
  98. inputStyle: {
  99. type: String,
  100. default: ''
  101. },
  102. selectStyle: {
  103. type: String,
  104. default: ''
  105. },
  106. overflow: {
  107. type: String,
  108. default: 'auto'
  109. },
  110. tags: {
  111. type: String,
  112. default: ''
  113. },
  114. binData: {
  115. type: Array,
  116. default: ''
  117. },
  118. selectIco: {
  119. type: Boolean,
  120. default: true
  121. },
  122. emptyTips: {
  123. type: String,
  124. default: '无匹配项'
  125. }
  126. },
  127. data() {
  128. return {
  129. odData: this.binData,
  130. nowData: this.binData,
  131. isShow: false,
  132. theValue: this.value,
  133. theDisabled: this.disabled
  134. }
  135. },
  136. watch: {
  137. value(val) {
  138. this.theValue = val;
  139. },
  140. //监听数据变化
  141. nowData: {
  142. handler: function() {
  143. this.nowData = this.binData;
  144. },
  145. deep: true
  146. },
  147. },
  148. computed: {
  149. show() {
  150. return this.isShow
  151. },
  152. filterCandidatesLength() {
  153. return this.binData.length
  154. }
  155. },
  156. methods: {
  157. //获取焦点
  158. theFocus(e) {
  159. this.nowData = this.odData;
  160. },
  161. //失去焦点
  162. theBlur(e) {
  163. this.$emit('blur', e)
  164. },
  165. //获取输入值
  166. theInput(e) {
  167. var val = e.detail.value;
  168. let data = [];
  169. var odData = this.odData;
  170. for (var i = 0; i < odData.length; i++) {
  171. var isHas = false;
  172. if (odData[i].value.indexOf(val) != -1) {
  173. data.push(odData[i])
  174. if (odData[i].value == val) {
  175. isHas = true;
  176. var arr = [];
  177. arr.push(odData[i].value)
  178. this.$emit('getBackVal', arr);
  179. }
  180. }
  181. if (!isHas) {
  182. var arr = [];
  183. arr.push(val)
  184. this.$emit('getBackVal', arr);
  185. }
  186. }
  187. this.nowData = data;
  188. },
  189. //下拉选中
  190. selectCheckbox(e) {
  191. var val = e.detail.value
  192. var str = val;
  193. let list = []
  194. let list2 = []
  195. if (typeof(str) != "string") {
  196. str = ""
  197. val.forEach(item => {
  198. if (item) {
  199. let itenShow = this.binData.find(it => it.id == item)
  200. if (itenShow) {
  201. list2.push(itenShow.value)
  202. }
  203. list.push(item)
  204. }
  205. })
  206. str = list2.join(",")
  207. } else {
  208. let itenShow = this.binData.find(it => it.id == str)
  209. if (itenShow) {
  210. str = itenShow.value
  211. }
  212. this.isShow = false;
  213. }
  214. this.$emit('getBackVal', str)
  215. this.theValue = str;
  216. }
  217. },
  218. }
  219. </script>
  220. <style lang="scss" scoped>
  221. .yealuo-select {
  222. // margin: 20rpx;
  223. max-width: 100%;
  224. position: relative;
  225. border: 1px solid #DCDFE6;
  226. border-radius: 4px;
  227. .yealuo-background {
  228. position: fixed;
  229. top: 0;
  230. left: 0;
  231. width: 750upx;
  232. height: 100%;
  233. }
  234. .yealuo-con {
  235. display: flex;
  236. align-items: center;
  237. justify-content: center;
  238. }
  239. }
  240. .uni-combox__input {
  241. padding: 15rpx;
  242. flex: 1;
  243. font-size: 28rpx;
  244. height: 65rpx;
  245. line-height: 65rpx;
  246. }
  247. .icon {
  248. color: #999;
  249. font-size: 26rpx;
  250. margin-right: 10rpx;
  251. }
  252. .item-close {
  253. text-align: center;
  254. font-size: 32rpx;
  255. border-top: 1px solid #f3f3f4;
  256. color: #8F8F94;
  257. }
  258. .uni-select__selector {
  259. /* #ifndef APP-NVUE */
  260. box-sizing: border-box;
  261. /* #endif */
  262. position: absolute;
  263. top: calc(100% + 12px);
  264. left: 0;
  265. width: 100%;
  266. background-color: #FFFFFF;
  267. border: 1px solid #EBEEF5;
  268. border-radius: 6px;
  269. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  270. z-index: 2;
  271. padding: 4px 0;
  272. z-index: 999;
  273. }
  274. .uni-select__selector-scroll {
  275. /* #ifndef APP-NVUE */
  276. max-height: 200px;
  277. box-sizing: border-box;
  278. /* #endif */
  279. padding: 0 20rpx;
  280. .select-item {
  281. width: 100%;
  282. color: #666;
  283. margin: 10rpx 0;
  284. .item-text {
  285. width: 100%;
  286. display: block;
  287. .select-text {
  288. margin-left: 10rpx;
  289. }
  290. }
  291. .active {
  292. font-weight: bold;
  293. }
  294. }
  295. .item-auto {
  296. overflow: auto;
  297. .item-text {
  298. width: max-content;
  299. }
  300. }
  301. .item-hide .item-text {
  302. overflow: hidden;
  303. text-overflow: ellipsis;
  304. white-space: nowrap;
  305. }
  306. }
  307. /* picker 弹出层通用的指示小三角 */
  308. .uni-popper__arrow,
  309. .uni-popper__arrow::after {
  310. position: absolute;
  311. display: block;
  312. width: 0;
  313. height: 0;
  314. border-color: transparent;
  315. border-style: solid;
  316. border-width: 6px;
  317. }
  318. .uni-popper__arrow {
  319. filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
  320. top: -6px;
  321. left: 10%;
  322. margin-right: 3px;
  323. border-top-width: 0;
  324. border-bottom-color: #EBEEF5;
  325. }
  326. .uni-popper__arrow::after {
  327. content: " ";
  328. top: 1px;
  329. margin-left: -6px;
  330. border-top-width: 0;
  331. border-bottom-color: #fff;
  332. }
  333. .uni-combox__selector-empty {
  334. /* #ifndef APP-NVUE */
  335. display: flex;
  336. cursor: pointer;
  337. /* #endif */
  338. line-height: 36px;
  339. font-size: 14px;
  340. text-align: center;
  341. // border-bottom: solid 1px #DDDDDD;
  342. padding: 0px 10px;
  343. }
  344. </style>