[英]Vue JS Watching deep nested object
免责声明:这是我第一次尝试构建一个 MVVM 应用程序,我之前也没有使用过 vue.js,所以很可能我的问题是一个更基本的问题的结果。
在我看来,我有两种带有复选框的块:
底层对象的结构如下:
{
"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
}
]
}
]
}
]
}
我的目标
选择复选框:
清除复选框
用户可以单击“清除”按钮,取消选中列表中的所有复选框(selected=false)。 此操作还应触发可选地禁用复选框和更新图标等的方法。
我目前的方法(似乎不太正确)
v-model
指令绑定到复选框元素的选中状态。v-on="change: checkboxChange(this)"
指令。 我想我需要以不同的方式做这部分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,
},
},
通知handler
和deep: 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.