formCreate.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <template>
  2. <view class="container">
  3. <uni-card :is-shadow="false" is-full>
  4. <text class="uni-h6">uni-forms 组件一般由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。</text>
  5. </uni-card>
  6. <uni-section title="基本用法" type="line">
  7. <view class="example">
  8. <!-- 基础用法,不包含校验规则 -->
  9. <uni-forms ref="baseForm" :model="baseFormData" labelWidth="80px">
  10. <uni-forms-item label="姓名" required>
  11. <uni-easyinput v-model="baseFormData.name" placeholder="请输入姓名" />
  12. </uni-forms-item>
  13. <uni-forms-item label="年龄" required>
  14. <uni-easyinput v-model="baseFormData.age" placeholder="请输入年龄" />
  15. </uni-forms-item>
  16. <uni-forms-item label="性别" required>
  17. <uni-data-checkbox v-model="baseFormData.sex" :localdata="sexs" />
  18. </uni-forms-item>
  19. <uni-forms-item label="兴趣爱好" required>
  20. <uni-data-checkbox v-model="baseFormData.hobby" multiple :localdata="hobbys" />
  21. </uni-forms-item>
  22. <uni-forms-item label="自我介绍">
  23. <uni-easyinput type="textarea" v-model="baseFormData.introduction" placeholder="请输入自我介绍" />
  24. </uni-forms-item>
  25. <uni-forms-item label="日期时间">
  26. <uni-datetime-picker type="datetime" return-type="timestamp"
  27. v-model="baseFormData.datetimesingle" />
  28. </uni-forms-item>
  29. <uni-forms-item label="选择城市">
  30. <uni-data-picker v-model="baseFormData.city" :localdata="cityData" popup-title="选择城市">
  31. </uni-data-picker>
  32. </uni-forms-item>
  33. <uni-forms-item label="选择技能">
  34. <uni-data-select v-model="baseFormData.skills" :localdata="skillsRange" >
  35. </uni-data-select>
  36. </uni-forms-item>
  37. </uni-forms>
  38. </view>
  39. </uni-section>
  40. <uni-section title="对齐方式" type="line">
  41. <view class="example">
  42. <view class="segmented-control">
  43. <uni-segmented-control :current="current" :values="items" @clickItem="onClickItem"
  44. styleType="button">
  45. </uni-segmented-control>
  46. </view>
  47. <!-- 展示不同的排列方式 -->
  48. <uni-forms ref="baseForm" :modelValue="alignmentFormData" :label-position="alignment">
  49. <uni-forms-item label="姓名" required>
  50. <uni-easyinput v-model="baseFormData.name" placeholder="请输入姓名" />
  51. </uni-forms-item>
  52. <uni-forms-item label="年龄" required>
  53. <uni-easyinput v-model="baseFormData.age" placeholder="请输入年龄" />
  54. </uni-forms-item>
  55. </uni-forms>
  56. </view>
  57. </uni-section>
  58. <uni-section title="表单校验" type="line">
  59. <view class="example">
  60. <!-- 基础表单校验 -->
  61. <uni-forms ref="valiForm" :rules="rules" :model="valiFormData" labelWidth="80px">
  62. <uni-forms-item label="姓名" required name="name">
  63. <uni-easyinput v-model="valiFormData.name" placeholder="请输入姓名" />
  64. </uni-forms-item>
  65. <uni-forms-item label="年龄" required name="age">
  66. <uni-easyinput v-model="valiFormData.age" placeholder="请输入年龄" />
  67. </uni-forms-item>
  68. <uni-forms-item label="自我介绍">
  69. <uni-easyinput type="textarea" v-model="valiFormData.introduction" placeholder="请输入自我介绍" />
  70. </uni-forms-item>
  71. </uni-forms>
  72. <button type="primary" @click="submit('valiForm')">提交</button>
  73. </view>
  74. </uni-section>
  75. <uni-section title="自定义校验规则" type="line">
  76. <view class="example">
  77. <!-- 自定义表单校验 -->
  78. <uni-forms ref="customForm" :rules="customRules" labelWidth="80px" :modelValue="customFormData">
  79. <uni-forms-item label="姓名" required name="name">
  80. <uni-easyinput v-model="customFormData.name" placeholder="请输入姓名" />
  81. </uni-forms-item>
  82. <uni-forms-item label="年龄" required name="age">
  83. <uni-easyinput v-model="customFormData.age" placeholder="请输入年龄" />
  84. </uni-forms-item>
  85. <uni-forms-item label="兴趣爱好" required name="hobby">
  86. <uni-data-checkbox v-model="customFormData.hobby" multiple :localdata="hobbys" />
  87. </uni-forms-item>
  88. </uni-forms>
  89. <button type="primary" @click="submit('customForm')">提交</button>
  90. </view>
  91. </uni-section>
  92. <uni-section title="动态表单" type="line">
  93. <view class="example">
  94. <!-- 动态表单校验 -->
  95. <uni-forms ref="dynamicForm" :rules="dynamicRules" :model="dynamicFormData" labelWidth="80px">
  96. <uni-forms-item label="邮箱" required name="email">
  97. <uni-easyinput v-model="dynamicFormData.email" placeholder="请输入姓名" />
  98. </uni-forms-item>
  99. <uni-forms-item v-for="(item,index) in dynamicFormData.domains" :key="item.id"
  100. :label="item.label+' '+index" required :rules="item.rules" :name="['domains',index,'value']">
  101. <view class="form-item">
  102. <uni-easyinput v-model="dynamicFormData.domains[index].value" placeholder="请输入域名" />
  103. <button class="button" size="mini" type="default" @click="del(item.id)">删除</button>
  104. </view>
  105. </uni-forms-item>
  106. </uni-forms>
  107. <view class="button-group">
  108. <button type="primary" size="mini" @click="add">新增域名</button>
  109. <button type="primary" size="mini" @click="submit('dynamicForm')">提交</button>
  110. </view>
  111. </view>
  112. </uni-section>
  113. </view>
  114. </template>
  115. <script>
  116. export default {
  117. data() {
  118. return {
  119. // 基础表单数据
  120. baseFormData: {
  121. name: '',
  122. age: '',
  123. introduction: '',
  124. sex: 2,
  125. hobby: [5],
  126. datetimesingle: 1627529992399,
  127. city: '',
  128. skills: 0
  129. },
  130. // 城市数据
  131. cityData: [{
  132. text: "北京",
  133. value: "10001",
  134. }, {
  135. text: "上海",
  136. value: "10002",
  137. }, {
  138. text: "深圳",
  139. value: "10004",
  140. }],
  141. skillsRange: [{
  142. value: 0,
  143. text: "编程"
  144. },
  145. {
  146. value: 1,
  147. text: "绘画"
  148. },
  149. {
  150. value: 2,
  151. text: "运动"
  152. },
  153. ],
  154. // 表单数据
  155. alignmentFormData: {
  156. name: '',
  157. age: '',
  158. },
  159. // 单选数据源
  160. sexs: [{
  161. text: '男',
  162. value: 0
  163. }, {
  164. text: '女',
  165. value: 1
  166. }, {
  167. text: '保密',
  168. value: 2
  169. }],
  170. // 多选数据源
  171. hobbys: [{
  172. text: '跑步',
  173. value: 0
  174. }, {
  175. text: '游泳',
  176. value: 1
  177. }, {
  178. text: '绘画',
  179. value: 2
  180. }, {
  181. text: '足球',
  182. value: 3
  183. }, {
  184. text: '篮球',
  185. value: 4
  186. }, {
  187. text: '其他',
  188. value: 5
  189. }],
  190. // 分段器数据
  191. current: 0,
  192. items: ['左对齐', '顶部对齐'],
  193. // 校验表单数据
  194. valiFormData: {
  195. name: '',
  196. age: '',
  197. introduction: '',
  198. },
  199. // 校验规则
  200. rules: {
  201. name: {
  202. rules: [{
  203. required: true,
  204. errorMessage: '姓名不能为空'
  205. }]
  206. },
  207. age: {
  208. rules: [{
  209. required: true,
  210. errorMessage: '年龄不能为空'
  211. }, {
  212. format: 'number',
  213. errorMessage: '年龄只能输入数字'
  214. }]
  215. }
  216. },
  217. // 自定义表单数据
  218. customFormData: {
  219. name: '',
  220. age: '',
  221. hobby: []
  222. },
  223. // 自定义表单校验规则
  224. customRules: {
  225. name: {
  226. rules: [{
  227. required: true,
  228. errorMessage: '姓名不能为空'
  229. }]
  230. },
  231. age: {
  232. rules: [{
  233. required: true,
  234. errorMessage: '年龄不能为空'
  235. }]
  236. },
  237. hobby: {
  238. rules: [{
  239. format: 'array'
  240. },
  241. {
  242. validateFunction: function(rule, value, data, callback) {
  243. if (value.length < 2) {
  244. callback('请至少勾选两个兴趣爱好')
  245. }
  246. return true
  247. }
  248. }
  249. ]
  250. }
  251. },
  252. dynamicFormData: {
  253. email: '',
  254. domains: []
  255. },
  256. dynamicLists: [],
  257. dynamicRules: {
  258. email: {
  259. rules: [{
  260. required: true,
  261. errorMessage: '域名不能为空'
  262. }, {
  263. format: 'email',
  264. errorMessage: '域名格式错误'
  265. }]
  266. }
  267. }
  268. }
  269. },
  270. computed: {
  271. // 处理表单排列切换
  272. alignment() {
  273. if (this.current === 0) return 'left'
  274. if (this.current === 1) return 'top'
  275. return 'left'
  276. }
  277. },
  278. onLoad() {},
  279. onReady() {
  280. // 设置自定义表单校验规则,必须在节点渲染完毕后执行
  281. this.$refs.customForm.setRules(this.customRules)
  282. },
  283. methods: {
  284. onClickItem(e) {
  285. console.log(e);
  286. this.current = e.currentIndex
  287. },
  288. add() {
  289. this.dynamicFormData.domains.push({
  290. label: '域名',
  291. value: '',
  292. rules: [{
  293. 'required': true,
  294. errorMessage: '域名项必填'
  295. }],
  296. id: Date.now()
  297. })
  298. },
  299. del(id) {
  300. let index = this.dynamicLists.findIndex(v => v.id === id)
  301. this.dynamicLists.splice(index, 1)
  302. },
  303. submit(ref) {
  304. console.log(this.baseFormData);
  305. this.$refs[ref].validate().then(res => {
  306. console.log('success', res);
  307. uni.showToast({
  308. title: `校验通过`
  309. })
  310. }).catch(err => {
  311. console.log('err', err);
  312. })
  313. },
  314. }
  315. }
  316. </script>
  317. <style lang="scss">
  318. .example {
  319. padding: 15px;
  320. background-color: #fff;
  321. }
  322. .segmented-control {
  323. margin-bottom: 15px;
  324. }
  325. .button-group {
  326. margin-top: 15px;
  327. display: flex;
  328. justify-content: space-around;
  329. }
  330. .form-item {
  331. display: flex;
  332. align-items: center;
  333. flex: 1;
  334. }
  335. .button {
  336. display: flex;
  337. align-items: center;
  338. height: 35px;
  339. line-height: 35px;
  340. margin-left: 10px;
  341. }
  342. </style>