uniapp/小程序,@input @change @blur 等事件,需要传额外参数的办法。

写在前面

经常在做表单的时候,会有多个相同的form-section(也就是需要提交的是一个格式相同的对象组成的数组).这个时候无论是input还是swtich或者picker,都会碰到一个问题,如何知道我当前的编辑的input是属于数组中的第几个对象,然后去修改对应对象的值(因为表单是遍历出来的是,所以绑定的函数肯定是同一个)。

主要场景如下

  • 酒店机票套餐等,需要填写多个用户身份信息。
  • 订单确认页面有多个商家(每个商家一个section,因为后台要分单),所以需要可以对每个子订单的是否使用余额、优惠券、积分抵扣,以及物流选项和发票信息,等进行维护
    uniapp/小程序,@input @change @blur 等事件,需要传额外参数的办法。_第1张图片

核心代码

<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等事件中利用下标去修改制定对象的属性。但是这样有明显的缺点

  1. 对于switch这样的组件,会有延迟(也就是子组件的change事件触发了,但是外层元素的点击事件还没冒泡到。。。所以这个时候activeRowIdx是空的)#亲测,要解决只能把逻辑代码写在settimeout里面等事件冒泡,这真是辣鸡做法#
  2. 多余的代码(每个form-item都需要申明事件)和变量(全局activeRowIdx)

你可能感兴趣的:(uniapp,小程序)