Vue监听对象属性实现联动效果

业务背景

在项目中有个这样的需求,一个表单里面存放的是供应商信息。同时要做成选择不同的供应商带出对应供应商的基础信息和公司资质文件,类似于一个级联操作通过选择的供应商Id,动态显示供应商信息。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAY3J1ZOeoi-W6j-WRmA==,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAY3J1ZOeoi-W6j-WRmA==,size_20,color_FFFFFF,t_70,g_se,x_16

 

思路分析

因为要实现动态显示的效果,所以我们需要请求后端接口拿到返回给前端的数据渲染到页面的表单上。这里前后端数据交互就不详细介绍了,那么下面进入实现方式。25dbe476e2aa47bea364497a602c9cab.png

 

 

 实现方式

因为选择供应商在表单里是一个下拉框组件,第一反应使用下拉款的Chang事件。当下拉框发生改变时去请求后端,下拉框的值通常是以键值对也就是[key:"",value:""]的形式存储。这里key就是供应商的Id,value就是供应商的名称。我们只需要拿着供应商的Id去请求后端接口查出此时的供应商信息再渲染到表单上即可实现。但是问题来了,一般情况下用下拉款的Chang事件已经可以解决这个业务需求了。但是因为公司项目封装性的原因,对下拉框组件进行了统一的封装处理做成了一个组件。我们直接改组件的话会影响到其它页面的使用。所以这时我们考虑用Vue的watch也就是监听事件来处理。当监听到供应商Id这个属性发生变化时进行我们的业务处理。

Vue监听:Vue.js 提供了一个方法 watch,它用于观察Vue实例上的数据变动。对应一个对象,键是观察表达式,值是对应回调。值也可以是方法名,或者是对象,包含选项。其中分为深度监听和浅度监听,深度监听可以逐级监听到对象下的每一个属性,每个属性发生变化时都会触发回调函数。 

watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听。那么这里我们需要监听的供应商的id是在updateRequest对象里的一个属性(manuSupplier)但其实这个属性也是一个对象类型。如果用深度监听的话就会一直触发回调函数,这样对内存的消耗是很大的,对用户的体验也不好。所以我们直接监听manuSupplier.id这个属性。

immediate:true。代表在wacth里声明了updateRequest.manuSupplier.id这个方法之后立即先去执行handler方法。在这里我们不需要立即执行handler方法只需要在这个值真的发生变化也就是选择不同的供应商id时才去执行里面的回调函数,所以不设置默认就为false。下面附上代码

 data() {
      return {
        data() {
          return {
            // 修改对象
            updateRequest: {
              hospEqpId: '',
              factSerialNo: '',
              deptId: '',
              hospCode: undefined,
              eqpProdId: '',
              contrId: '',
              eqpTagValueList: [],
              dealerSupplierId: '',
              manuSupplierId: '',
              'manuSupplier': {
                'id': '',
                'type': '',
                'supName': '',
                'phone': '',
                'contactName': '',
                'contactPhone': '',
                'license': '',
                'hospCode': '',
                'createDateTime': [],
                'companyCertification': '',
                'certificationInfoList': [],
                'invalidFile': []
              },
              'dealerSupplier': {
                'id': '',
                'type': '',
                'supName': '',
                'phone': '',
                'contactName': '',
                'contactPhone': '',
                'license': '',
                'hospCode': '',
                'createDateTime': [],
                'companyCertification': '',
                'certificationInfoList': [],
                'invalidFile': []
              }
            },
            // 查询供应商请求对象
            querySupplierRequest: {
              hospCode: '',
              id: ''
            }
          }
        }
      }
    }
 watch: {
      // 监听厂家供应商下拉框属性值改变
      'updateRequest.manuSupplier': {
        handler(newVal, oldVal) {
          if (newVal) {
            this.querySupplierRequest.hospCode = this.hospCode
            this.querySupplierRequest.id = newVal
            queryBySupplierIdRequest(this.querySupplierRequest).then(res => {
              this.updateRequest.manuSupplier = res
            })
          }
        }
      },
      // 监听经销供应商下拉框属性值改变
      'updateRequest.dealerSupplier.id': {
        handler(newVal, oldVal) {
          if (newVal) {
            this.querySupplierRequest.hospCode = this.hospCode
            this.querySupplierRequest.id = newVal
            queryBySupplierIdRequest(querySupplierRequest).then(res => {
              this.updateRequest.dealerSupplier = res
            })
          }
        }
      }
    }

写到这一步的时候我以为已经解决问题了,但是此时返回页面查看表单发现了一个问题。两次监    听执行完之后,厂家供应商的信息是错误的。厂家供应商的信息被覆盖成经销供应商的信息。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAY3J1ZOeoi-W6j-WRmA==,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAY3J1ZOeoi-W6j-WRmA==,size_20,color_FFFFFF,t_70,g_se,x_16

后面经过debug调式后发现在监听到经销供应商被赋值发生变化后,因为两次监听后触发回调函数请求的后端接口是同一个,并且用到的请求参数querySupplierRequest是定义在data数据源的一个常量。因为请求是ajax封装的异步请求,在你监听到经销供应商id变化后又反向给请求参数对象queryRequest的id赋值了变成了经销商的id。所以这时厂家供应商id其实被赋值成了经销商的id。这时你去请求后端其实查询的还是经销商的信息。所以在请求后端接口时不能使用同一个常量对象改成局部对象。下面附上改正后代码

 watch: {
    // 监听厂家供应商下拉框属性值改变
    'updateRequest.manuSupplier.id': {
      handler(newVal,oldVal) {
        if (newVal) {
          let obj={
            id : '',
            hospCode : ''
          }
          obj.hospCode=this.hospCode
          obj.id=newVal
          queryBySupplierIdRequest(obj).then(res => {
            this.updateRequest.manuSupplier = res
          })
        }
      }
    },
    // 监听经销供应商下拉框属性值改变
    'updateRequest.dealerSupplier.id': {
      handler(newVal,oldVal) {
        if (newVal) {
          let obj={
            id : '',
            hospCode : ''
          }
          obj.hospCode=this.hospCode
          obj.id=newVal
          queryBySupplierIdRequest(obj).then(res => {
            this.updateRequest.dealerSupplier = res
          })
        }
      }
    }
  }

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAY3J1ZOeoi-W6j-WRmA==,size_20,color_FFFFFF,t_70,g_se,x_16

可以看到此时厂家供应商的信息才是正确的,且每次切换供应商都会监听到去执行你的业务代码重新赋值给表单实现了联动的效果。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue2中,我们可以使用watch来监听一个函数的变化。具体的用法是在watch对象中添加一个属性属性名为要监听的函数的名称,属性值为一个回调函数。当这个函数发生变化时,回调函数会被触发。例如: ```javascript new Vue({ data: { count: 0 }, watch: { // 监听函数的名称为myFunction myFunction: function(newVal, oldVal) { // 在函数发生变化时执行的操作 console.log('函数发生了变化'); console.log('新值为:', newVal); console.log('旧值为:', oldVal); } }, methods: { // 定义一个函数myFunction myFunction: function() { // 函数的具体实现 } } }) ``` 在上面的例子中,我们定义了一个名为myFunction的函数,并将它添加到watch对象中。当myFunction函数发生变化时,回调函数会被触发,打印出新值和旧值。这样我们就可以在函数发生变化时执行一些操作了。 #### 引用[.reference_title] - *1* *3* [Vue2 Watch监听](https://blog.csdn.net/m0_61093181/article/details/130379188)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vue的watch监听函数](https://blog.csdn.net/wwf1225/article/details/106590301)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值