yealuo-select.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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 ? false : nowData.length">
  5. <slot name="left"></slot>
  6. <input
  7. :disabled="theDisabled"
  8. :placeholder="placeholder"
  9. v-model="theValue"
  10. @input="theInput"
  11. @focus="theFocus"
  12. @blur="theBlur"
  13. autocomplete="off"
  14. />
  15. <slot name="right" v-if="selectIco">
  16. <svg
  17. class="icon"
  18. v-if="!isShow"
  19. style="width: 1em; height: 1em; vertical-align: middle; fill: currentColor; overflow: hidden"
  20. viewBox="0 0 1024 1024"
  21. version="1.1"
  22. xmlns="http://www.w3.org/2000/svg"
  23. p-id="530"
  24. >
  25. <path
  26. 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"
  27. p-id="531"
  28. ></path>
  29. </svg>
  30. <svg
  31. class="icon"
  32. v-else
  33. style="width: 1em; height: 1em; vertical-align: middle; fill: currentColor; overflow: hidden"
  34. viewBox="0 0 1024 1024"
  35. version="1.1"
  36. xmlns="http://www.w3.org/2000/svg"
  37. p-id="1927"
  38. >
  39. <path
  40. 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"
  41. p-id="1928"
  42. ></path>
  43. </svg>
  44. </slot>
  45. </view>
  46. <view class="yealuo-select" v-show="show" :style="selectStyle">
  47. <view class="data">
  48. <radio-group v-if="checkType == 'radio'" @change="selectCheckbox">
  49. <view class="select-item" :class="'item-' + overflow" v-for="(item, index) in nowData" :key="index">
  50. <label class="item-text" :class="{ active: theValue == item.value }">
  51. <radio name="name1" checked v-if="theValue == item.value" :value="item.value + '|' + item.id"></radio>
  52. <radio name="name1" v-else :value="item.value + '|' + item.id"></radio>
  53. {{ item.value }}
  54. </label>
  55. </view>
  56. </radio-group>
  57. <checkbox-group v-else-if="checkType == 'checkbox'" @change="selectCheckbox">
  58. <view class="select-item" :class="'item-' + overflow" v-for="(item, index) in nowData" :key="index">
  59. <label class="item-text" :class="{ active: theValue.indexOf(item.value) != -1 }">
  60. <checkbox name="name1" checked v-if="theValue.indexOf(item.value) != -1" :value="item.value + '|' + item.id"></checkbox>
  61. <checkbox name="name1" v-else :value="item.value + '|' + item.id"></checkbox>
  62. {{ item.value }}
  63. </label>
  64. </view>
  65. </checkbox-group>
  66. <radio-group v-else @change="selectCheckbox">
  67. <view class="select-item" :class="'item-' + overflow" v-for="(item, index) in nowData" :key="index">
  68. <label class="item-text" :class="{ active: theValue == item.value }">
  69. <radio name="name1" style="display: none" checked v-if="theValue == item.value" :value="item.value + '|' + item.id"></radio>
  70. <radio name="name1" style="display: none" v-else :value="item.value + '|' + item.id"></radio>
  71. {{ item.value }}
  72. </label>
  73. </view>
  74. </radio-group>
  75. </view>
  76. <view class="item-close" @tap="isShow = false">收起</view>
  77. </view>
  78. </view>
  79. </template>
  80. <script>
  81. let fontUnit = 'upx';
  82. // #ifdef MP-WEIXIN
  83. fontUnit = 'rpx';
  84. // #endif
  85. export default {
  86. name: 'yealuoInputs',
  87. props: {
  88. placeholder: {
  89. type: String,
  90. default: ''
  91. },
  92. value: {
  93. type: String,
  94. default: ''
  95. },
  96. checkType: {
  97. type: String,
  98. default: ''
  99. },
  100. itemKey: {
  101. type: String,
  102. default: ''
  103. },
  104. width: {
  105. type: String,
  106. default: '600'
  107. },
  108. disabled: {
  109. type: Boolean,
  110. default: false
  111. },
  112. inputStyle: {
  113. type: String,
  114. default: ''
  115. },
  116. selectStyle: {
  117. type: String,
  118. default: ''
  119. },
  120. overflow: {
  121. type: String,
  122. default: 'auto'
  123. },
  124. tags: {
  125. type: String,
  126. default: ''
  127. },
  128. binData: {
  129. type: Array,
  130. default: ''
  131. },
  132. selectIco: {
  133. type: Boolean,
  134. default: false
  135. }
  136. },
  137. data() {
  138. return {
  139. odData: this.binData,
  140. nowData: this.binData,
  141. isShow: false,
  142. theValue: this.value,
  143. theDisabled: this.disabled
  144. };
  145. },
  146. watch: {
  147. value(val) {
  148. this.theValue = val;
  149. },
  150. //监听数据变化
  151. // nowData: {
  152. // handler: function () {
  153. // this.nowData = this.binData;
  154. // },
  155. // deep: true
  156. // }
  157. },
  158. computed: {
  159. show() {
  160. return this.isShow && this.nowData.length;
  161. }
  162. },
  163. methods: {
  164. //获取焦点
  165. theFocus(e) {
  166. this.nowData = this.odData;
  167. },
  168. //失去焦点
  169. theBlur(e) {
  170. this.$emit('blur', e);
  171. },
  172. //获取输入值
  173. theInput(e) {
  174. var val = e.detail.value;
  175. let data = [];
  176. var odData = this.odData;
  177. for (var i = 0; i < odData.length; i++) {
  178. var isHas = false;
  179. if (odData[i].value.indexOf(val) > -1) {
  180. data.push(odData[i]);
  181. if (odData[i].value == val) {
  182. isHas = true;
  183. var arr = [];
  184. arr.push(odData[i].value + '|' + odData[i].id);
  185. this.$emit('getBackVal', arr);
  186. }
  187. }
  188. if (!isHas) {
  189. var arr = [];
  190. arr.push(val);
  191. this.$emit('getBackVal', arr);
  192. }
  193. }
  194. this.nowData = data;
  195. },
  196. //下拉选中
  197. selectCheckbox(e) {
  198. var val = e.target.value;
  199. var str = val;
  200. if (typeof str != 'string') {
  201. str = '';
  202. for (var i = 0; i < val.length; i++) {
  203. var vt = val[i].split('|');
  204. str += i > 0 ? ',' + vt[0] : vt[0];
  205. }
  206. } else {
  207. this.isShow = false;
  208. str = str.split('|')[0];
  209. }
  210. this.$emit('getBackVal', val + '|' + this.tags);
  211. this.theValue = str;
  212. },
  213. clearData() {
  214. this.theValue = '';
  215. }
  216. }
  217. };
  218. </script>
  219. <style lang="scss" scoped>
  220. .yealuo-select {
  221. max-width: 100%;
  222. border: solid 1px #dcdfe6;
  223. border-radius: 4px;
  224. padding: 6px;
  225. position: relative;
  226. .yealuo-background {
  227. position: fixed;
  228. top: 0;
  229. left: 0;
  230. width: 750upx;
  231. height: 100%;
  232. }
  233. .yealuo-con {
  234. display: flex;
  235. align-items: center;
  236. justify-content: center;
  237. input {
  238. flex: 1;
  239. margin: 0 6upx;
  240. }
  241. }
  242. .yealuo-select {
  243. border: 1px solid #f3f3f4;
  244. position: absolute;
  245. z-index: 999;
  246. background: #fff;
  247. width: 100%;
  248. .data {
  249. max-height: 600upx;
  250. padding: 10upx;
  251. overflow: auto;
  252. .select-item {
  253. width: 100%;
  254. color: #666;
  255. .item-text {
  256. width: 100%;
  257. display: block;
  258. }
  259. .active {
  260. font-weight: bold;
  261. }
  262. }
  263. .item-auto {
  264. overflow: auto;
  265. .item-text {
  266. width: max-content;
  267. }
  268. }
  269. .item-hide .item-text {
  270. overflow: hidden;
  271. text-overflow: ellipsis;
  272. white-space: nowrap;
  273. }
  274. }
  275. .item-close {
  276. padding: 20upx;
  277. text-align: center;
  278. font-size: 32upx;
  279. border-top: 1px solid #f3f3f4;
  280. color: #8f8f94;
  281. }
  282. }
  283. }
  284. </style>