当前位置: 首页 > article >正文

watch监听事件未生效

在 Vue.js 中尝试使用 watch 监听 form.deptId 属性的变化,但在某些情况下监听器没有触发。

具体表现为:

  1. 在打开“添加”对话框时,watch 监听器可以正常检测到 deptId 的变化。
  2. 但是在打开“修改”对话框时,即使 form.deptId 被更新了,监听器却没有触发,导致后续逻辑没有执行。

        <el-col :span="12">
            <el-form-item label="归属部门" prop="deptId">
              <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" 
               placeholder="请选择归属部门" />
            </el-form-item>
          </el-col>   

     ...

       watch: {
        // 监听deptId
        'form.deptId': 'currDeptChange'
     },
     ...
     //新增/修改表单监听部门id改变事件
    currDeptChange(val) {
      console.log('在currDeptChange', val)
      this.userOptions = [];
      this.form.userIds = [];

      listUser({ DeptId: val, status: "0" }).then(response => {
        console.log("查询用户列表response:", response);

        this.userOptions = response.data.dataSource;
      });
      // if (val) {
      // 	this.queryStaff()
      // }
    },

这个问题的根源在于 Vue 的响应式系统的工作方式。Vue 的响应式系统可以自动检测数据的变化,但它对对象嵌套属性的直接赋值有一些限制。下面是详细解释:

1. Vue 的响应式系统原理

Vue 使用 Object.defineProperty(Vue 3 中是基于 Proxy)来拦截对象的属性访问和赋值操作,从而实现响应式数据。当你在 Vue 的 data 中定义一个对象属性时,Vue 会把这个对象及其属性转换为响应式对象。之后,Vue 可以监测到这个属性的变化,并相应地更新 DOM 或触发 watch 监听器。

2. 问题的原因:直接赋值对嵌套属性的影响

data 中定义的对象本身是响应式的,但嵌套属性的直接赋值可能不会被 Vue 的响应式系统监测到。尤其是当你在 data 中定义了一个对象(例如 form),但没有定义其中的嵌套属性(如 form.deptId),Vue 不会自动监测到对 deptId 的直接赋值。

在你的情况中,deptId 属性可能在初始化 form 对象时没有被 Vue 监测到,因此在 handleUpdate 方法中直接赋值 this.form.deptId = response.data.belongsDeptId 时,Vue 的响应式系统不会检测到 deptId 的变化,所以 watch 监听器不会被触发。

3. 解决方法:使用 $set

Vue 提供了 $set 方法,用于确保某个属性变为响应式。$set 方法的工作原理是在对象上“定义”一个新的属性或重写现有属性,同时确保该属性会被 Vue 响应式系统检测到。


this.$set(this.form, 'deptId', response.data.belongsDeptId);

使用 $set 可以手动通知 Vue 这个属性的变化,使其重新进入响应式系统的监测范围,因此 Vue 可以触发 watch 监听器。$set 实际上是在对象上重新定义了这个属性,使得 Vue 可以检测到变化。

改后的代码
    handleUpdate(row) {

      console.log("row", row);

      this.reset();
      const id = row.id;
      console.log("修改按钮操作id", id);

      // getUserProfile(id).then(response => {
      Get(id).then(response => {

        this.form = response.data;
         
        //变了这里
        // 使用 $set 确保 deptId 的更新能触发 watch
        this.$set(this.form, 'deptId', response.data.belongsDeptId);

        GetEnableUser({ id: id, DistinguishingSigns: "2" }).then(res => {
          console.log("resresresres", res);

          this.userOptions = res.data.users;

 
          //这里直接赋值
          // this.form.userIds = res.data.userIds

          this.$set(this.form, "userIds", res.data.userIds);
          console.log("用户iduserIds", this.form);

        });


        this.open = true;
        this.title = "修改值日信息";


      });
    },

总结

  • 原因:在 Vue 中,直接赋值未在 data 中定义的嵌套属性不会被响应式系统监测到。
  • 原理:Vue 的响应式系统基于 Object.defineProperty 或 Proxy。未在 data 中初始化的嵌套属性不会自动变成响应式。
  • 解决:使用 $set 手动添加或更新属性,使 Vue 的响应式系统可以检测到变化,并触发 watch 监听器。

http://www.kler.cn/a/396381.html

相关文章:

  • 智能化护士排班系统的设计与实现(文末附源码)
  • 系统架构设计师第二版口诀
  • 一种时间戳对齐的方法(离线)
  • 前端知识点---this的用法 , this动态绑定(Javascript)
  • 【WPF】Prism学习(二)
  • 通过Python 调整Excel行高、列宽
  • 网络动力学
  • 飞创直线电机模组 VS 传统丝杆模组:谁是自动化传动领域的王者?
  • HarmonyOS ArkTs 解决流式传输编码问题
  • 一文1800字使用Jmeter进行http接口性能测试!
  • Vue Shop Vite官网、Vue Admin Plus官网、前端框架、演示地址、源码、文档
  • Swift从0开始学习 函数和闭包 day2
  • PostgreSQL 数据加密和数据解密
  • Vue 学习随笔系列十五 -- 数组遍历方法
  • 基于VUE实现语音通话:边录边转发送语言消息、 播放pcm 音频
  • Vue.js 前端框架入门
  • Python学习从0到1 day27 Python 高阶技巧 ③ 设计模式 — 单例模式
  • Wi-Fi背后的工作原理与技术发展历程介绍【无线通信小百科】
  • 柯桥生活英语口语学习“面坨了”英语怎么表达?
  • Ubuntu联网问题处理
  • springboot的依赖实现原理:spring-boot-starter-parent解析
  • P3-3.【结构化程序设计】第三节——知识要点:while语句、do-while语句和for语句
  • 移植LVGL8.2以及移植过程的理解
  • Element表格show-overflow-tooltip属性
  • C#入门 023 什么是类(Class)
  • java 操作Mongodb