tm-form.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <template>
  2. <view class="tm-form fulled">
  3. <slot></slot>
  4. </view>
  5. </template>
  6. <script>
  7. /**
  8. * 表单组件
  9. * @property {String} url = [] 提交时的网址。
  10. * @property {String} method = [POST | GET] 提交时的的方法
  11. * @property {Object} header = [] 提交时的头部对象数据
  12. * @property {Function} submit 验证成功会返回数据集合,验证失败返回false,点击提交按钮时触发。表单内部一定放一个tm-button,注意navtie-type="form"表单专用属性,<tm-button navtie-type="form">提交/tm-button>
  13. * @property {Function} request 请求成功触发的事件,返回请求的数据。
  14. *
  15. */
  16. export default {
  17. name:"tm-form",
  18. props:{
  19. //提交时的网址。如果填写提交时,不会请求数据。
  20. url:{
  21. type:String,
  22. default:''
  23. },
  24. //请求方法
  25. method:{
  26. type:String,
  27. default:'POST' //POST | GET
  28. },
  29. //头部数据
  30. header:{
  31. type:Object,
  32. default:()=>{
  33. return {};
  34. }
  35. }
  36. },
  37. data() {
  38. return {
  39. };
  40. },
  41. mounted() {
  42. this.$nextTick(async function(){
  43. //#ifdef APP-VUE || APP-PLUS
  44. await uni.$tm.sleep(50);
  45. //#endif
  46. this.init()
  47. })
  48. },
  49. methods: {
  50. findeChildren(cl){
  51. let t = this;
  52. let mubiao = ['tm-input','tm-button','tm-groupradio','tm-groupcheckbox','tm-upload','tm-rate','tm-slider','tm-stepper','tm-switch']
  53. let jg = [];
  54. function start(item){
  55. let tag = item.$options?.name;
  56. let index = mubiao.findIndex(citem=>{
  57. return tag == citem;
  58. })
  59. if(index>-1){
  60. if(tag=='tm-button'&&item.$props.navtieType=='form'){
  61. item.onclick = function(){
  62. t.$nextTick(function(){
  63. t.formSub(jg);
  64. })
  65. }
  66. }else{
  67. if(tag!='tm-button'&&item.$props.name!=''){
  68. jg.push(item)
  69. }
  70. }
  71. }else{
  72. if(Array.isArray(item.$children)){
  73. item.$children.forEach(zcl=>{
  74. start(zcl)
  75. })
  76. }
  77. }
  78. }
  79. start(cl);
  80. },
  81. init() {
  82. let cl = this;
  83. //#ifdef H5 || APP-VUE || APP-PLUS
  84. cl = this.$children[0];
  85. //#endif
  86. this.$nextTick(function(){
  87. this.findeChildren(cl);
  88. })
  89. },
  90. async formSub(cl){
  91. let bdData={};
  92. let verify=true;
  93. for(let i=0;i<cl.length;i++){
  94. let item = cl[i];
  95. let tagname = item.$options?.name;
  96. if(tagname=='tm-upload'){
  97. bdData[item.$props.name] = item.getFile();
  98. }else if(tagname=='tm-input'){
  99. if(item.$props.required){
  100. if(!item.verifyInput()){
  101. verify=false;
  102. break;
  103. return;
  104. }
  105. }
  106. bdData[item.$props.name] = item.$props.value;
  107. }else if(tagname=='tm-groupradio' || tagname== 'tm-groupcheckbox'){
  108. bdData[item.$props.name] = item.getVal();
  109. }else if(tagname=='tm-slider' || tagname=='tm-stepper' || tagname=='tm-rate' || tagname=='tm-switch'){
  110. bdData[item.$props.name] = item.$props.value;
  111. }
  112. }
  113. if(verify===true){
  114. this.$emit('submit',bdData)
  115. if(this.url!==""){
  116. let rulst = null;
  117. if(this.method.toLocaleLowerCase()=='get'){
  118. rulst = await uni.$tm.request.get(this.url,bdData,this.header)
  119. }else if(this.method.toLocaleLowerCase()=='post'){
  120. rulst = await uni.$tm.request.post(this.url,bdData,this.header)
  121. }
  122. this.$emit('request',rulst)
  123. }
  124. }else{
  125. this.$emit('submit',false)
  126. }
  127. },
  128. findeChildren_off(cl){
  129. let t = this;
  130. let mubiao = ['tm-input','tm-button','tm-groupradio','tm-groupcheckbox','tm-upload','tm-rate','tm-slider','tm-stepper','tm-switch']
  131. let jg = [];
  132. function start(item){
  133. let tag = item.$options?.name;
  134. let index = mubiao.findIndex(citem=>{
  135. return tag == citem;
  136. })
  137. if(index>-1){
  138. if(tag=='tm-button'&&item.$props.navtieType=='form'){
  139. }else{
  140. if(tag!='tm-button'&&item.$props.name!=''){
  141. jg.push(item)
  142. }
  143. }
  144. }else{
  145. if(Array.isArray(item.$children)){
  146. item.$children.forEach(zcl=>{
  147. start(zcl)
  148. })
  149. }
  150. }
  151. }
  152. start(cl);
  153. return jg;
  154. },
  155. //手动获取当前表单对象数据,Promise风格。
  156. getFormData(){
  157. let t = this;
  158. return new Promise((su,fl)=>{
  159. t.$nextTick(function(){
  160. let clPren = t.$children[0];
  161. //#ifdef H5
  162. clPren = t.$children[0].$children[0].$children[0];
  163. //#endif
  164. let cl = t.findeChildren_off(clPren);
  165. let bdData={};
  166. let verify=true;
  167. for(let i=0;i<cl.length;i++){
  168. let item = cl[i];
  169. let tagname = item.$options?.name;
  170. if(tagname=='tm-upload'){
  171. bdData[item.$props.name] = item.getFile();
  172. }else if(tagname=='tm-input'){
  173. bdData[item.$props.name] = item.$props.value;
  174. }else if(tagname=='tm-groupradio' || tagname== 'tm-groupcheckbox'){
  175. bdData[item.$props.name] = item.getVal();
  176. }else if(tagname=='tm-slider' || tagname=='tm-stepper' || tagname=='tm-rate' || tagname=='tm-switch'){
  177. bdData[item.$props.name] = item.$props.value;
  178. }
  179. }
  180. su(bdData);
  181. })
  182. })
  183. }
  184. },
  185. }
  186. </script>
  187. <style lang="scss">
  188. </style>