MultiLineInput.vue 5.2 KB

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