写在前面
经常在做表单的时候,会有多个相同的form-section(也就是需要提交的是一个格式相同的对象组成的数组).这个时候无论是input还是swtich或者picker,都会碰到一个问题,如何知道我当前的编辑的input是属于数组中的第几个对象,然后去修改对应对象的值(因为表单是遍历出来的是,所以绑定的函数肯定是同一个)。
主要场景如下
- 酒店机票套餐等,需要填写多个用户身份信息。
- 订单确认页面有多个商家(每个商家一个section,因为后台要分单),所以需要可以对每个子订单的是否使用余额、优惠券、积分抵扣,以及物流选项和发票信息,等进行维护
核心代码
<switch :checked="postData.need_invoice[biz_id]" @change="faPiaoChange($event,biz_id)" color="#04B600" />
faPiaoChange (e,biz_id) {
const open = e.detail.value
if (open) {
this.postData.need_invoice[biz_id] = 1
} else {
this.postData.need_invoice[biz_id] = 0
}
}
额外提供一个不好的示例
<div @click="changeShip(biz_id)" class="o_title">
<span>运费选择</span>
<span style="text-align:right; color: #888;" class="flex flex-vertical-c">
<span>
<block v-if="postData.shipping_name[biz_id]">
{{postData.shipping_name[biz_id]}} {{(' ' + (orderInfo.Order_Shipping.Price > 0 ? '¥'+orderInfo.Order_Shipping.Price : '免运费'))}}
</block>
<block v-else>请选择物流</block>
</span>
<layout-icon type="iconicon-arrow-right" class="right" color="#999"></layout-icon>
</span>
</div>
//标记当前操作的下标
changeShip (biz_id) {
this.activeBizId = biz_id
this.ship_current = this.postData.shipping_id[biz_id]
}
//错误的用法
ShipRadioChange (e) {
const val = e.detail.value
this.ship_current = val
this.postData.shipping_id[this.activeBizId] = val
this.postData.shipping_name[this.activeBizId] = val === 'is_store' ? '到店自取' : this.popupExpressCompanys[val] // 也要设置下name
// 更改物流,需要重新获取信息,计算运费
this.checkOrderParam()
},
总结
挺简单的,百度一搜就有了。但是之前一直使用的是给form-item的外层标签,加一个点击事件,然后全局维护一个activeRowIdx,来保存当前操作的下标,然后在input等事件中利用下标去修改制定对象的属性。但是这样有明显的缺点
- 对于switch这样的组件,会有延迟(也就是子组件的change事件触发了,但是外层元素的点击事件还没冒泡到。。。所以这个时候activeRowIdx是空的)#亲测,要解决只能把逻辑代码写在settimeout里面等事件冒泡,这真是辣鸡做法#
- 多余的代码(每个form-item都需要申明事件)和变量(全局activeRowIdx)