MultiLineInput.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <div :style="{'margin-bottom':isLast?'0':'.3rem'}" :class="['multipIpt',{'border':border,'inline':inline,'check':select}]">
  3. <span class="prefix" v-if="content.prefix">{{content.prefix}}</span>
  4. <div class="sticP" :style="{paddingRight:content.suffix?'1rem':'0'}">
  5. <div class="iptWrap">
  6. <template v-for="(item,idx) in content.iptLis">
  7. <input v-if="content.iptLis.length>1"
  8. class="contentVal"
  9. :type="content.type=='number'?'number':'text'"
  10. :style="{'width':1/content.iptLis.length*100-3+'%'}"
  11. :key="item.placeholder+idx"
  12. v-model="item.value"
  13. :placeholder="item.placeholder"
  14. @input="changeVal($event,idx,content.type)"
  15. @blur="blur"
  16. @focus="focus"
  17. @click="handleClick">
  18. <input v-show="content.iptLis.length==1" class="contentVal"
  19. :type="content.type=='number'?'number':'text'"
  20. :placeholder="content.placeholder"
  21. v-model="item.value"
  22. @input="changeVal($event,idx,content.type)"
  23. @blur="blur"
  24. @focus="focus"
  25. @click="handleClick">
  26. <span v-if="idx == 0&&content.iptLis.length>1">/</span>
  27. </template>
  28. </div>
  29. </div>
  30. <span class="suffix" v-if="content.suffix">{{content.suffix}}</span>
  31. </div>
  32. </template>
  33. <script>
  34. import { getModelExpStr,isIos } from '@utils/tools';
  35. import $ from 'jquery';
  36. export default {
  37. props:{
  38. msg:{
  39. default:'',
  40. type:String
  41. },
  42. part:{
  43. type:Object,
  44. require: true
  45. },
  46. border:{//最外层边框
  47. default:true,
  48. type:Boolean
  49. },
  50. inline:{ //是否行内元素
  51. default:false,
  52. type:Boolean
  53. },
  54. select:{ //是否选中
  55. default:false,
  56. type:Boolean
  57. },
  58. isLast:{ //是否为最后一个
  59. default:false,
  60. type:Boolean
  61. },
  62. },
  63. data(){
  64. return {
  65. content:{},
  66. txt:this.part.value || '', //回读用
  67. tmpArr:[]
  68. }
  69. },
  70. mounted(){
  71. this.content = getModelExpStr(this.msg,this.txt)
  72. },
  73. methods:{
  74. changeVal(e,num,type){
  75. let tmpTxt = '',arr=this.tmpArr
  76. // document.activeElement.scrollIntoViewIfNeeded(true);
  77. if(type == 'number'){
  78. e.currentTarget.value = e.currentTarget.value.replace(/^\.$/,'').slice(0,9)
  79. }
  80. arr[num]=e.currentTarget.value
  81. tmpTxt=arr.join('/')
  82. this.txt = tmpTxt
  83. this.content = getModelExpStr(this.msg,this.txt)
  84. // this.$emit('changeMultipVal',e.currentTarget.value,num)
  85. const select = this.part.select;
  86. // if(!select){return}
  87. const newData = Object.assign({},this.part,{value:this.txt,controlType:3,valueP:this.txt});
  88. this.$emit("updata",newData);
  89. this.$emit('handleInp',this.txt);
  90. },
  91. blur(){
  92. // 如果该项未选中,则不存值
  93. // $(".btscroll").css({'position':'fixed'})
  94. $(".foot").css({'display':'block'})
  95. document.activeElement.scrollIntoView({behavior: "smooth",block:'end'})
  96. // document.activeElement.scrollIntoViewIfNeeded(true);
  97. // setTimeout(()=>{
  98. // document.activeElement.scrollIntoViewIfNeeded(true);
  99. // },300)
  100. },
  101. focus(){
  102. if(isIos()){
  103. // $(".btscroll").css({'position':'absolute'})
  104. $(".foot").css({'display':'none'})
  105. }
  106. },
  107. handleClick(e){
  108. // 点击输入框时不选中该项
  109. // document.activeElement.scrollIntoViewIfNeeded(true);
  110. e.stopPropagation();
  111. }
  112. },
  113. watch:{
  114. part:{//清空时更新
  115. handler(newVal,oldVal){
  116. this.txt = newVal.value;
  117. this.content = getModelExpStr(this.msg,this.txt)
  118. },
  119. deep:true
  120. }
  121. },
  122. }
  123. </script>
  124. <style lang="less" scoped>
  125. @import '../less/base.less';
  126. .multipIpt {
  127. width: 100%;
  128. // height: .74rem /* 74/100 */;
  129. line-height: .74rem /* 74/100 */;
  130. // border: 1px solid #DFE0E4;
  131. // border-radius: .08rem /* 8/100 */;
  132. padding: 0 .12rem 0 .26rem;
  133. box-sizing: border-box;
  134. position: relative;
  135. margin-bottom: .3rem;
  136. .contentVal {
  137. font-size: .3rem /* 30/100 */;
  138. color: #colors[theme];
  139. text-align: left;
  140. border: 0 none;
  141. // border-bottom: 1px solid #b0afaf !important;
  142. border-radius: 0;
  143. // background-color: #fff;
  144. background: transparent;
  145. outline-color: invert;
  146. height: .38rem;
  147. line-height: .38rem;
  148. width: 100%;
  149. padding:0 0.1rem;
  150. box-sizing: border-box;
  151. }
  152. }
  153. .border{
  154. border: 1px solid #DFE0E4;
  155. border-radius: 2rem
  156. }
  157. .inline{
  158. display: inline-block;
  159. vertical-align: middle;
  160. color: #colors[text];
  161. padding: 0;
  162. margin:0;
  163. height: auto /* 74/100 */;
  164. line-height: .36rem /* 74/100 */;
  165. }
  166. .prefix {
  167. float: left;
  168. color: #666;
  169. line-height: .72rem;
  170. }
  171. .suffix {
  172. position: absolute;
  173. right: .1rem;
  174. top: .2rem;
  175. width: 1rem;
  176. text-align: right;
  177. text-align: left;
  178. color: #666;
  179. line-height: .36rem;
  180. }
  181. .sticP {
  182. width: 100%;
  183. padding-right: 1rem;
  184. box-sizing: border-box;
  185. .iptWrap {
  186. // width: 100%;
  187. position: relative;
  188. overflow: hidden;
  189. min-width: 1rem;
  190. span {
  191. color: #666;
  192. }
  193. }
  194. }
  195. .check{
  196. color: #colors[theme];
  197. }
  198. </style>