page-multipage-form 办理类服务(多流程)模板

从开发者工具 v2.25.1-rc 版本开始支持。

解释:具有导航栏的办理类服务(多流程)模板,通常用来完成复杂多流程表单填写提交工作。本模板包含多个组件,可根据实际需要进行增删,支持代码的二次开发满足个性化诉求。

示例

扫码体验

代码示例

百度智能小程序

请使用百度APP扫码

页面内容

模板包含两个页面:多步骤表单页提交状态页(成功 / 失败)

多步骤表单页

将整个表单划分为多个步骤,每个步骤收集不同分类的信息,开发者可自定义步骤长度,在每个步骤中提供了单选、多选、输入、上传图片等多种表单类型,可根据实际需求选用,模板还提供了提交状态页面,用于展示表单提交结果。
页面路径:index/index

page-multipage-form 办理类服务(多流程)模板 - 图2

page-multipage-form 办理类服务(多流程)模板 - 图3

page-multipage-form 办理类服务(多流程)模板 - 图4

代码示例

以下为部分代码示例注解

  • SWAN
  • JSON
  1. <!-- 页面加载 -->
  2. <smt-page-status s-if="isPageLoading || pageResult"
  3. class="content"
  4. loading="{{isPageLoading}}"
  5. icon="{{errorConfig[pageResult].icon}}"
  6. title="{{errorConfig[pageResult].title}}"
  7. desc="{{errorConfig[pageResult].desc}}"
  8. showBtn="{{errorConfig[pageResult].showBtn}}"
  9. bind:smtreloading="check">
  10. </smt-page-status>
  11. <!-- 办理类服务(多流程)模板 -->
  12. <view s-else class="{{isFullScreen ? 'iphonexs' : 'normal'}}">
  13. <view class="thick-divid">
  14. <gov-steps
  15. active="{{active}}"
  16. line-width="{{2}}"
  17. steps="{{step}}">
  18. </gov-steps>
  19. </view>
  20. <!-- 页面一 -->
  21. <block s-if="{{active === 1}}">
  22. <view class="thick-divid">
  23. <gov-page-title title="标题一" size="middle" hasBorder></gov-page-title>
  24. <!--
  25. gov-input 输入框
  26. 1. ipt-item-type: short/long 标题可是四字或六字
  27. 在一个表单内,建议使用一致的标题宽度设置
  28. 2.ipt-value= "{{formData.key}}" //
  29. ipt-name="key"
  30. ipt-error-info="{{errorInfp.key+Error}}"
  31. 三项必配置,且key要一致
  32. 3. 输入框中清除事件 iptKeyClean, input事件 iptKeyInput
  33. -->
  34. <gov-input
  35. type="idcard"
  36. ipt-item-type="idcard"
  37. ipt-title="身份证号"
  38. ipt-value="{{formData.idcard}}"
  39. iptErrorInfo="{{errorInfo.idcardError}}"
  40. ipt-name="idcard"
  41. maxlength="18"
  42. ipt-item-width="100%"
  43. placeholder-content="请输入"
  44. bindiptclean="iptKeyClean"
  45. bindkeyinput="iptKeyInput"
  46. bindiptblur="iptblursfz">
  47. </gov-input>
  48. <gov-input
  49. type="number"
  50. ipt-item-type="phone"
  51. ipt-title="手机号"
  52. ipt-value="{{formData.phone}}"
  53. ipt-error-info="{{errorInfo.phoneError}}"
  54. ipt-name="phone"
  55. maxlength="11"
  56. ipt-item-width="100%"
  57. placeholder-content="请输入"
  58. bindiptclean="iptKeyClean"
  59. bindkeyinput="iptKeyInput"
  60. bindiptblur="iptblursjh">
  61. </gov-input>
  62. <gov-picker
  63. label="日期"
  64. mode=date
  65. placeholder="请选择"
  66. labelWidth="4em"
  67. data-value="date"
  68. start="{{startDate}}"
  69. end="{{endDate}}"
  70. errStatus="{{errorInfo.dateError}}"
  71. value="{{formData.date}}"
  72. bindchange="handleChange1">
  73. </gov-picker>
  74. <gov-picker
  75. label="所在位置"
  76. mode="location"
  77. placeholder="请选择"
  78. labelWidth="4em"
  79. noborder="{{true}}"
  80. errStatus="{{errorInfo.placeError}}"
  81. locationName="{{formData.place}}"
  82. bindchoosesuccess="choosesuccess"
  83. bindchoosefail="choosefail">
  84. </gov-picker>
  85. </view>
  86. <view>
  87. <gov-page-title title="标题二" size="middle" hasBorder></gov-page-title>
  88. <gov-input
  89. type="text"
  90. ipt-item-type="short"
  91. ipt-title="输入框"
  92. ipt-value="{{formData.iptone}}"
  93. ipt-error-info="{{errorInfo.iptoneError}}"
  94. ipt-name="iptone"
  95. ipt-item-width="100%"
  96. placeholder-content="请输入"
  97. bindiptclean="iptKeyClean"
  98. bindkeyinput="iptKeyInput">
  99. </gov-input>
  100. <gov-input
  101. type="text"
  102. ipt-item-type="short"
  103. ipt-title="输入框"
  104. ipt-value="{{formData.ipttwo}}"
  105. ipt-error-info="{{errorInfo.ipttwoError}}"
  106. ipt-notic-info="{{noticInfo.iptNoticInfo}}"
  107. ipt-name="ipttwo"
  108. ipt-item-width="100%"
  109. placeholder-content="请输入"
  110. bindiptclean="iptKeyClean"
  111. bindkeyinput="iptKeyInput">
  112. </gov-input>
  113. <gov-picker
  114. mode="selector"
  115. range="{{options.singPicker}}"
  116. label="选择框"
  117. labelWidth="4em"
  118. bindchange="handleChange3"
  119. value="{{formData.sltsingle}}"
  120. rangeKey="name"
  121. errStatus="{{errorInfo.sltsingleError}}"
  122. placeholder="请选择">
  123. </gov-picker>
  124. <gov-cascade
  125. range="{{options.cascader}}"
  126. label="选择框"
  127. value="{{formData.sltdouble}}"
  128. rangeKey="name"
  129. labelWidth="4em"
  130. tips="{{['请选择', '请选择', '请选择']}}"
  131. bindchange="cacadaChange"
  132. errStatus= "{{errorInfo.sltdoubleError}}"
  133. placeholder="{{['请选择', '请选择', '请选择']}}"/>
  134. </view>
  135. </block>
  136. <!-- 页面二 -->
  137. <block s-if="{{active === 2}}">
  138. <view class="thick-divid">
  139. <gov-page-title title="单选标题" size="middle" hasBorder></gov-page-title>
  140. <view class="radios">
  141. <gov-radio-group
  142. inline="{{false}}"
  143. option-key="name"
  144. active-color="#2772fb"
  145. options="{{options.radiosValue}}"
  146. bindchange="radioChange"
  147. value="{{formData.radios}}">
  148. </gov-radio-group>
  149. </view>
  150. </view>
  151. <view>
  152. <gov-page-title title="多选标题" size="middle" hasBorder></gov-page-title>
  153. <view class="checkboxs">
  154. <gov-checkbox-group
  155. groupStyle="border-bottom: 0.6rpx solid #e6e6e6 !important"
  156. inline="{{false}}"
  157. option-key="name"
  158. activeColor="#2772fb"
  159. options="{{options.checkboxsValue}}"
  160. bindchange="checkboxChange"
  161. gov-checkbox-group="border"
  162. value="{{formData.checkbox}}">
  163. </gov-checkbox-group>
  164. <gov-checkbox
  165. bindchange="noHas"
  166. activeColor="#2772fb"
  167. value="{{formData.nochecked}}"
  168. gov-checkbox="border">
  169. 不含以上情况
  170. </gov-checkbox>
  171. </view>
  172. </view>
  173. </block>
  174. <!-- 页面三 -->
  175. <block s-if="{{active === 3}}">
  176. <view class="thick-divid">
  177. <gov-textarea
  178. gov-textarea-wrap="textareaWrap"
  179. gov-textarea-element="textareaElement"
  180. bindinput="iptTextarea"
  181. placeholder="请输入"
  182. head="长文本输入框标题"
  183. value="{{formData.textBox}}"
  184. maxlength="100">
  185. </gov-textarea>
  186. </view>
  187. <view>
  188. <view class="upload-title">
  189. <gov-page-title title="上传照片标题" size="middle" hasBorder></gov-page-title>
  190. </view>
  191. <gov-upload
  192. count="5"
  193. gov-tips="tips"
  194. bind:delete="clickDelete"
  195. bind:uploadsuccess="uploadsuccess"
  196. bind:urlempty="urlempty"
  197. bind:previewfail="previewfail"
  198. tips="最多支持5张图片,单张体积10M一下"
  199. imageList="{{formData.uploadphotos}}"
  200. limitSize="10"/>
  201. </view>
  202. </block>
  203. <!-- 页面四 -->
  204. <block s-if="{{active === 4}}">
  205. <view s-for="informateFour.lists trackBy item" class="thick-divid">
  206. <gov-page-title title="{{item.bigTitle}}" size="middle" hasBorder></gov-page-title>
  207. <gov-list-item s-for="items, index in item.msg trackBy index"
  208. gov-list-item="listItem"
  209. gov-label="label"
  210. label="{{items.title}}"
  211. labelWidth="4em"
  212. content="{{items.sub}}"
  213. clickable
  214. border="{{index !== item.msg.length-1}}">
  215. </gov-list-item>
  216. </view>
  217. <view s-for="informateFour.expand trackBy item" class="thick-divid">
  218. <gov-page-title
  219. title="{{item.bigTitle}}"
  220. size="middle"
  221. gov-title-wrap="titleWrap">
  222. </gov-page-title>
  223. <view class="expand-wrap">
  224. <gov-text-collapse
  225. text="{{item.msg}}"
  226. line="5">
  227. </gov-text-collapse>
  228. </view>
  229. </view>
  230. <view>
  231. <gov-page-title title="{{informateFour.photos.bigTitle}}" size="middle" hasBorder></gov-page-title>
  232. <view class="gov-image-wrap">
  233. <gov-image-item s-for="informateFour.photos.msg trackBy item"
  234. class="gov-plate-img"
  235. image-src="{{item}}"
  236. image-width="224.64"
  237. image-height="224.64"
  238. border-radius="10">
  239. </gov-image-item>
  240. </view>
  241. </view>
  242. <view class="wen">
  243. <gov-prompt>
  244. <view slot="title">温馨提示:</view>
  245. <view slot="content">此板块为提示区,可用户提醒用户业务填写中的注意事项及要求<view class="prompt-view" bindtap="toView">点击查看</view>
  246. </view>
  247. </gov-prompt>
  248. </view>
  249. </block>
  250. <view class="bottoms"></view>
  251. <view class="tail">
  252. <view class="btn">
  253. <gov-button s-if="{{active !== 1}}"
  254. button-size="middle"
  255. button-text="上一步"
  256. button-color="plain"
  257. bindtap="prev">
  258. </gov-button>
  259. <gov-button
  260. button-size="{{active===1 ? 'large':'middle'}}"
  261. button-text="{{active === 4 ? '提交': '下一步'}}"
  262. button-color="default"
  263. bindtap="next">
  264. </gov-button>
  265. </view>
  266. <view s-if="{{isFullScreen}}" class="{{isFullScreen ? 'iphonex-safe-height': 'normal-height'}}"></view>
  267. </view>
  268. </view>
  1. {
  2. "navigationBarTitleText": "办理类服务(多流程)模板",
  3. "backgroundColor": "#fff",
  4. "navigationBarBackgroundColor": "#fff",
  5. "navigationBarTextStyle": "black",
  6. "usingComponents": {
  7. "gov-steps": "@smt-ui/component-gov/src/steps",
  8. "gov-prompt": "@smt-ui/component-gov/src/prompt",
  9. "gov-picker": "@smt-ui/component-gov/src/picker",
  10. "gov-upload": "@smt-ui/component-gov/src/upload",
  11. "gov-input": "@smt-ui/component-gov/src/input",
  12. "gov-button": "@smt-ui/component-gov/src/button",
  13. "gov-cascade": "@smt-ui/component-gov/src/cascade",
  14. "gov-image-item": "@smt-ui/component-gov/src/image-item",
  15. "gov-textarea": "@smt-ui/component-gov/src/textarea",
  16. "gov-page-title": "@smt-ui/component-gov/src/page-title",
  17. "smt-page-status": "@smt-ui/component/src/page-status",
  18. "gov-list-item": "@smt-ui/component-gov/src/list-item",
  19. "gov-radio-group": "@smt-ui/component-gov/src/radio-group",
  20. "gov-checkbox": "@smt-ui/component-gov/src/checkbox",
  21. "gov-checkbox-group": "@smt-ui/component-gov/src/checkbox-group",
  22. "gov-text-collapse": "@smt-ui/component-gov/src/text-collapse"
  23. }
  24. }
  • 获取页面数据

  • JS

  1. /**
  2. * 发送请求
  3. *
  4. * @param {Object=} data 请求接口参数
  5. */
  6. getDetail(data = {}) {
  7. //【需替换】:获取内容详情所需要的数据,请修改 url 字段为真实的请求地址,该接口仅做示例
  8. let params = {
  9. url: 'https://www.ceshi.com',
  10. method: 'GET',
  11. data,
  12. success: res => {
  13. // 接口正常返回处理逻辑
  14. if (+res.code === 0) {
  15. if (Object.keys(res.data).length) {
  16. this.setData({
  17. // merge 本地数据和异步数据赋值给 options
  18. options: {...this.data.options, ...res.data}
  19. }, () => {
  20. this.setData({
  21. isPageLoading: false,
  22. pageResult: ''
  23. });
  24. });
  25. }
  26. else {
  27. // 没有数据
  28. this.setData({
  29. isPageLoading: false,
  30. pageResult: 'noData'
  31. });
  32. }
  33. }
  34. else {
  35. // 接口异常处理逻辑
  36. this.setData({
  37. isPageLoading: false,
  38. pageResult: 'warning'
  39. });
  40. }
  41. },
  42. fail: err => {
  43. // 接口异常处理逻辑
  44. this.setData({
  45. isPageLoading: false,
  46. pageResult: 'warning'
  47. });
  48. }
  49. };
  50. swan.request(params);
  51. }
  • 点击下一步按钮触发事件

  • JS

  1. /**
  2. * 点击下一步按钮触发事件
  3. */
  4. next() {
  5. // 输入框,选择框根据错误状态判断 toast 的状态,
  6. // 多选,单选,长文本,上传照片根据 value 值判断 toast 的状态
  7. const formData = this.data.formData;
  8. // datas 用于保存第四步提交时的参数字符串
  9. let datas = '';
  10. // this.data.active 表示当前处于第几步
  11. switch (this.data.active) {
  12. case 1:
  13. this.verifyfirst();
  14. break;
  15. case 2:
  16. // 判断第二步单选框是否选择了
  17. if (Number(formData.radios) < 0) {
  18. this.showToast('请选择单选');
  19. return;
  20. }
  21. // 判断第二步多选框是否选择了
  22. if (!formData.checkbox.length && !formData.nochecked) {
  23. this.showToast('请选择多选');
  24. return;
  25. }
  26. // 第二步校验通过,设置页面索引为 3
  27. this.setData('active', 3);
  28. break;
  29. case 3:
  30. // 判断第三步长文本输入框是否有值
  31. if (!formData.textBox) {
  32. this.showToast('请输入长文本');
  33. return;
  34. }
  35. // 第三步校验通过,设置页面索引为 4
  36. this.setData('active', 4);
  37. // 核对信息页面的数据
  38. this.fiveInfor();
  39. break;
  40. case 4:
  41. // 设置参数,参数格式可根据业务接口自定义
  42. datas = JSON.stringify(this.parameter());
  43. swan.showModal({
  44. title: '信息确认信息',
  45. content: '请确认填写的信息无误,提交后不支持修改',
  46. confirmText: '确认提交',
  47. confirmColor: '#108EE9',
  48. cancelText: '返回修改',
  49. cancelColor: '#999',
  50. success(res) {
  51. if (res.confirm) {
  52. // 此处可自定义业务逻辑
  53. swan.redirectTo({
  54. url: `../result/result?result=${datas}`
  55. });
  56. }
  57. }
  58. });
  59. break;
  60. }
  61. }
  • 页面一点击下一步时的校验逻辑

  • JS

  1. /**
  2. * 第一步的校验函数,错误飘红,并toast提示相关错误信息
  3. */
  4. verifyfirst() {
  5. // 页面中所有表单输入值的集合
  6. const formData = this.data.formData;
  7. // 页面一中 input,选择框的 error 状态设置
  8. let errorInfo = {
  9. // checkIdcard、checkPhone、checkEmpty校验方法的详细说明可看 utils.js
  10. idcardError: checkIdcard(formData.idcard),
  11. phoneError: checkPhone(formData.phone),
  12. dateError: !formData.date,
  13. placeError: !formData.place,
  14. iptoneError: checkEmpty(formData.iptone, '请输入输入框一'),
  15. ipttwoError: checkEmpty(formData.ipttwo, '请输入输入框二'),
  16. sltsingleError: formData.sltsingle < 0,
  17. sltdoubleError: formData.sltdouble.length !== 3
  18. };
  19. this.setData({errorInfo}, () => {
  20. this.showCurToast();
  21. });
  22. }

提交状态页

用于展示表单提交结果。

页面路径:result/result

page-multipage-form 办理类服务(多流程)模板 - 图5

page-multipage-form 办理类服务(多流程)模板 - 图6

代码示例

  • SWAN
  • JSON
  1. <smt-page-status s-if="isPageLoading || errorPage"
  2. class="content"
  3. loading="{{isPageLoading}}"
  4. icon="{{errorConfig[errorPage].icon}}"
  5. title="{{errorConfig[errorPage].title}}"
  6. desc="{{errorConfig[errorPage].desc}}"
  7. showBtn="{{errorConfig[errorPage].showBtn}}"
  8. bind:smtreloading="check">
  9. </smt-page-status>
  10. <view s-else class='wrap'>
  11. <gov-page-result
  12. iconName="{{icon.iconName}}"
  13. iconColor="{{icon.iconColor}}"
  14. gov-main-btn="gov-main-btn"
  15. gov-ext-info-text="gov-ext-info-text"
  16. title="{{pageResult.title}}"
  17. desc="{{pageResult.desc}}"
  18. main-btn-text="回到首页"
  19. sub-btn-text="辅助按钮"
  20. bind:goback="goBack"
  21. bind:viewdetails="viewDetails">
  22. <view slot="suppl-cont" class="list" s-if="{{pageResult.list}}">
  23. <view s-for="pageResult.list trackBy item" class='every'>
  24. <text>{{item.title}}</text>
  25. <text>{{item.sub}}</text>
  26. </view>
  27. </view>
  28. </gov-page-result>
  29. </view>
  1. {
  2. "navigationBarTitleText": "结果页",
  3. "backgroundColor": "#fff",
  4. "navigationBarBackgroundColor": "#fff",
  5. "navigationBarTextStyle": "black",
  6. "usingComponents": {
  7. "ga-button": "@smt-ui/component-gov/src/button",
  8. "smt-page-status": "@smt-ui/component/src/page-status",
  9. "gov-page-result": "@smt-ui/component-gov/src/page-result"
  10. }
  11. }
  • 页面初始化

  • JS

  1. /**
  2. * 页面加载时触发
  3. *
  4. * @param {Object} options 提交页面传的参数
  5. * @param {string} options.result 传的数据
  6. */
  7. onLoad(options) {
  8. this.setData({
  9. // 页面需要展示的数据,依赖server端返回
  10. pageResult: '',
  11. options: JSON.parse(options.result)
  12. });
  13. let icon;
  14. // 根据接口返回的数据或提交页面传入的数据判断需要展示的 icon 类型
  15. if (pageResult.data.type !== 'success') {
  16. icon = {
  17. iconName: 'warning-o',
  18. iconColor: '#c40311'
  19. };
  20. this.setData({icon});
  21. }
  22. }
  • 点击“返回首页”按钮触发事件

  • JS

  1. /**
  2. * 返回首页
  3. */
  4. goBack() {
  5. //【需替换】:请为 url 设置真实的首页路径
  6. swan.redirectTo({
  7. url: ''
  8. });
  9. }
  • 点击“辅助按钮”按钮触发事件

  • JS

  1. /**
  2. * 辅助按钮
  3. */
  4. viewDetails() {
  5. //【需替换】:请为 url 设置真实的跳转页面路径
  6. swan.redirectTo({
  7. url: ''
  8. });
  9. }

npm 依赖

名称版本号
@smt-ui/component-govlatest
@smt-ui/componentlatest

Bug & Tip

  • Tip:该模板使用了 ES6 语法,需要开启开发者工具的增强编译,操作步骤参看开启说明;同时也需开启上传代码时样式自动补全。
  • Tip:以上代码示例为小程序前端代码,可直接在模拟器和真机预览。
  • Tip:模板中使用的是测试数据,你需要从接口中获取真实的数据。