繁体   English   中英

Vue JS 观看深层嵌套对象

[英]Vue JS Watching deep nested object

免责声明:这是我第一次尝试构建一个 MVVM 应用程序,我之前也没有使用过 vue.js,所以很可能我的问题是一个更基本的问题的结果。


在我看来,我有两种带有复选框的块:

  • 类型 1:块/复选框
  • 类型 2:块/标题/复选框

底层对象的结构如下:

{
  "someTopLevelSetting": "someValue",
  "blocks": [
    {
      "name": "someBlockName",
      "categryLevel": "false",
      "variables": [
        {
          "name": "someVarName",
          "value": "someVarValue",
          "selected": false,
          "disabled": false
        }
      ]
    },
    {
      "name": "someOtherBlockName",
      "categryLevel": "true",
      "variables": [
        {
          "name": "someVarName",
          "value": "someVarValue",
          "categories": [
            {
              "name": "SomeCatName",
              "value": "someCatValue",
              "selected": false,
              "disabled": false
            }
          ]
        }
      ]
    }
  ]
}

我的目标

选择复选框:

  1. 用户点击复选框,复选框被选中(selected=true)
  2. 会触发一个方法来检查是否需要禁用任何其他复选框(禁用 = 真)。 (如果这个方法确实禁用了任何东西,它也会再次调用自己,因为其他项目可能反过来依赖于禁用的项目)
  3. 另一种方法更新其他一些东西,比如图标等

清除复选框

用户可以单击“清除”按钮,取消选中列表中的所有复选框(selected=false)。 此操作还应触发可选地禁用复选框和更新图标等的方法。

我目前的方法(似乎不太正确)

  • 数据模型的 selected 属性通过v-model指令绑定到复选框元素的选中状态。
  • disabled 属性(来自模型)绑定到元素的 class 和 disabled 属性。 该状态通过上述方法设置。
  • 为了初始化禁用复选框和更改某些图标的方法,我使用了v-on="change: checkboxChange(this)"指令。 我想我需要以不同的方式做这部分
  • clearList 方法通过v-on="click: clearList(this)"

我当前设置的问题是当以编程方式清除复选框时(即不是通过用户交互),更改事件不会触发。

我想要的是什么
对我来说,最合乎逻辑的做法是使用this.$watch并跟踪模型中的变化,而不是监听 DOM 事件。

一旦发生变化,我就需要确定哪个确切的项目发生了变化,然后采取行动。 我试图创建一个观察blocks数组的$watch函数。 这似乎很好地接受了更改,但它返回了完整的对象,而不是已更改的单个属性。 这个对象也缺少一些方便的辅助属性,比如$parent

我可以想到一些让应用程序工作的hacky方法(例如在我的 clearList 方法中手动触发更改事件等),但我的用例似乎非常标准,所以我希望可能有一种更优雅的方法来处理这个问题。

您可以使用 'watch' 方法.. 例如,如果您的数据是:

data: {
    block: {
        checkbox: {
            active:false
        },
        someotherprop: {
            changeme: 0
        }
    }
}

你可以这样做:

data: {...},
watch: {
   'block.checkbox.active': function() {
        // checkbox active state has changed
        this.block.someotherprop.changeme = 5;
    } 
}

如果您想查看整个对象及其所有属性,而不仅仅是一个属性,您可以这样做:

 data() {
    return {
       object: {
          prop1: "a",
          prop2: "b",
       }    
    }
 },
 watch: {
    object: {
        handler(newVal, oldVal) {
            // do something with the object
        },
        deep: true,
    },
},

通知handlerdeep: true

如果您只想观看prop1您可以执行以下操作:

watch: { 
    'object.prop1' : function(newVal, oldVal) { 
        // do something here 
     }
}

此处未提及的其他解决方案:使用deep选项。

watch:{
  block: {
    handler: function () {console.log("changed") },
    deep: true
  }
}

由于没有人回复并且我现在已经解决/解决了这个问题,我认为发布我的解决方案可能很有用。 请注意,我不确定我的解决方案是如何处理这些类型的事情,但它确实有效。

而不是使用这个事件监听器v-on="change: checkboxChange(this)"我现在使用一个自定义指令来监听 selected 和 disabled 模型属性,像这样: v-on-filter-change="selected, disabled"

该指令如下所示:

directives: {
    'on-filter-change': function(newVal, oldVal) {
        // When the input elements are first rendered, the on-filter-change directive is called as well, 
        // but I only want stuff to happen when a user does someting, so I return when there is no valid old value
        if (typeof oldVal === 'undefined') {
            return false;
        }
        // Do stuff here
        // this.vm is a handy attribute that contains some vue instance information as well as the current object
        // this.expression is another useful attribute with which you can assess which event has taken place
    }
},

if 子句似乎有点 hacky,但我找不到其他方法。 至少这一切都有效。

也许这对将来的某人有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM