先上一个效果图,要实现的效果就是报销明细的组别里,填写相应的字段,点击新增一条报销,可以在组别里增加一组。提交时计算出报销的总金额,确认无误后提交。
UI组件我这边使用的是vant weapp组件库
第一步是基础的组件json配置
{
"usingComponents": {
"van-field": "@vant/weapp/field/index",
"van-button": "@vant/weapp/button/index"
}
}
首先,我们先对初始的页面进行布局,本来我是想将所有的可见项都放进一个form表单中一起提交,但是碍于接口采用了报销明细条目特殊符号拼接的传参方式,如果全部放进去,遍历表单数据的时候会不方便,所以,我只把明细组别里的数据放进表单中。
wxml:
审核单号
申请人姓名
申请人所属部门
wxss:
.form-group-title-box {
padding-left: 8px;
padding-bottom: 8px;
}
.form-group-title {
color: rgb(132, 145, 151);
font-size: 12px;
}
.group-separator {
background-color: rgb(245, 246, 249);
height: 8px;
}
.add-new-button {
height: 44px;
text-align: center;
}
.add-new-button {
font-size: 16px;
color: rgb(24, 113, 248);
}
.submit-button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: rgb(24, 113, 248);
height: 50px;
}
.picker {
display: flex;
flex-direction: row;
align-items: center;
height: 40px;
background-color: white
}
.picker-inner-title {
width: 100px;
padding-left: 16px;
font-size: 14px;
color: rgb(100, 101, 102);
}
.picker-inner-text {
font-size: 14px;
}
.submit-button-inner-text {
font-size: 14px;
color: white;
text-align: center;
}
page {
height: 100%;
background-color: rgb(245, 246, 249)
}
写js之前想到一个问题,需求是报销的申请是可以回来查看的,所以,只能使用map+数组的形式来构建列表,这样问题就来了,我填写完一组后,新增一组,我该如何把之前已经填写的那一组放进列表数组里去呢。。。,不解决这个问题,填写完一组新增就白写了。。。
本来我一开始的做法是,声明一个文件内的全局对象,每次监听到input值变化的时候,我就更新那个对象,新增时,将这个对象push进数组,不过事实证明,我想多了,这样push进来了,但是数组是倒着的。。。,只能另想一个解决方案。
我为啥不直接修改数组里面每一个对象的属性呢,但是,setData可以修改属性对象里面的值吗,最后,我找到了方法
js
Page({
data: {
array: ['差旅费', '误餐费', '招待费', '燃料费', '过桥过路费', '办公费', '电话费', '房租', '水电', '运费', '取暖费', '修理费', '其他'],
orderNumText: '10000922222',
nameText: wx.getStorageSync('userinfo').opername,
depText: wx.getStorageSync('userinfo').depname,
namePlaceholder: '请输入姓名',
depPlaceholder: '请输入部门',
orderText: '单据号',
pickerIndex: 0,
dic: {
typename: '',
memo: '',
fee: '',
imgurl: '',
},
subs: [{
typename: '',
memo: '',
fee: '',
imgurl: '',
}],
imgurl: ''
},
handleAddNew: function (e) {
// console.log(this.data.dic)
// this.data.subs.push(this.data.dic)
console.log(this.data.subs)
var newDic = {
typename: '',
memo: '',
fee: '',
imgurl: '',
}
this.data.subs.push(newDic)
this.setData({
subs: this.data.subs
})
console.log(this.data.subs)
},
onOrderNumChange: function(e) {
this.setData({
orderNumText: e.detail
})
},
onUserNameChange: function(e) {
this.setData({
nameText: e.detail
})
},
onDepNameChange: function(e) {
this.setData({
depText: e.detail
})
},
onTypenNameChage: function (e) {
console.log('onTypenNameChage')
var val = e.detail
let index = e.currentTarget.dataset.index
let typename = 'subs['+ index +'].typename'
this.setData({
[typename]: val
})
},
onUseChange: function (e) {
var val = e.detail
let index = e.currentTarget.dataset.index
let memo = 'subs['+ index +'].memo'
this.setData({
[memo]: val
})
},
onAmountChange: function (e) {
var val = e.detail
let index = e.currentTarget.dataset.index
let fee = 'subs['+ index +'].fee'
this.setData({
[fee]: val
})
},
onAppendixChange: function (e) {
},
bindPickerChange: function (e) {
// console.log('bindPickerChange')
// this.setData({
// pickerIndex: e.detail.value
// })
var obj = e.detail
var val = this.data.array[obj.value]
console.log(this.data.array)
let index = e.currentTarget.dataset.index
let typename = 'subs['+ index +'].typename'
this.setData({
[typename]: val
})
},
formSubmit: function (e) {
let obj = e.detail.value
if (JSON.stringify(obj) === '{}') {
wx.showToast({
title: '请填写至少一条报销申请后再提交',
icon: 'none',
duration: 2000
})
return
}
var dataArr = ''
var totalamount = 0
for (let key in obj) {
if (key.indexOf("amount") != -1) {
totalamount += parseInt(obj[key])
}
let ele = obj[key]
dataArr = dataArr + '$' + `${ele}`
}
console.log(totalamount)
},
})
好了,到这里问题就解决了,还有一个小问题,就是,如果将input和 picker绑定在一起的时候,可能会出现两种情况
第一、弹出的键盘遮挡住picker
第二、弹出picker选中其中一项,选中的值不会填充进input
所以,咱们尽量不要将input和picker一起使用,我的处理是,自定义了一个组件,view里面包含了一个用作前缀的view,还有中心用于文本展示的text
wxml
类别
{{subs[index].typename}}
wxss
.picker {
display: flex;
flex-direction: row;
align-items: center;
height: 40px;
background-color: white
}
.picker-inner-title {
width: 100px;
padding-left: 16px;
font-size: 14px;
color: rgb(100, 101, 102);
}
.picker-inner-text {
font-size: 14px;
}
效果几乎和vant的input组件一样
嘿嘿