Vue JS观看深层嵌套对象

Hen*_*rik 41 javascript mvvm vue.js

免责声明:这是我第一次尝试构建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
            }
          ]
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我的目标

选择复选框:

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

清除复选框

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

我目前的方法 (看起来不太正确)

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

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

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

一旦发生变化,我就需要确定哪个确切的项目已更改,并采取相应措施.我试图创建一个$watch观察blocks数组的函数.这似乎可以很好地了解变化,但它返回的是完整对象,而不是已更改的单个属性.此对象也缺少一些方便的帮助器属性,如$parent.

我可以想到一些使应用程序工作的hacky方法(比如在我的clearList方法中手动触发更改事件等),但我的用例似乎很标准,所以我希望有一种更优雅的方法来处理它.

web*_*kit 70

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

data: {
    block: {
        checkbox: {
            active:false
        },
        someotherprop: {
            changeme: 0
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

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


pee*_*lte 23

如果您希望将对象作为一个整体与其所有属性一起观看,而不仅仅是一个属性,则可以执行以下操作:

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

通知handlerdeep: true

  • @SylvainAttoumani是的:在我的例子中:`watch:{'object.prop1':function(newVal,oldVal){//在这里做点什么}}` (14认同)
  • @Hendrik不用担心,我希望这可以帮助那些有同样问题的人 (3认同)

Hen*_*rik 7

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

v-on="change: checkboxChange(this)"我没有使用这个事件监听器,而是使用一个自定义指令来监听选定和禁用的模型属性,如下所示: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
    }
},
Run Code Online (Sandbox Code Playgroud)

if子句似乎有点hacky,但我找不到另一种方式.至少这一切都有效.

也许这将对未来的某些人有用.


Gra*_*ick 5

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

watch:{
  block: {
    handler: function () {console.log("changed") },
    deep: true
  }
}
Run Code Online (Sandbox Code Playgroud)