【问题标题】:Ignore some properties in a deep watch for VueJs忽略 VueJs 深入观察中的一些属性
【发布时间】:2019-07-12 07:52:43
【问题描述】:

我正在为一个 vue 应用程序开发自动保存功能,每次对 vue 应用程序数据进行更改时,它都会向 api 发送数据。使用 vue watch 时是否可以忽略对象的某些属性?该对象有多个值,我想监视以自动保存,并且只有 1 或 2 个会被忽略,因此为我想要的所有属性设置监视函数似乎没有意义,而只是忽略 1我没有。

这是数据的基本结构:

data:{
  template: {
    name: "Template",
    id: 1,
    variables: [
      {
        name: "v1",
        color: "#fff",
        group: 1,
        isSelected: true
      },
      {
        name: "v2",
        color: "#fff",
        group: 3,
        isSelected: false
      }
    ]
  }
}

以及基本的手表功能:

watch: {
  template: {
    handler: function(){
      this.save();
    },
    deep: true
  }
}

模板中变量的 isSelected 字段仅用于 UI,我希望手表忽略该字段的更改,因为它们不会被保存。我不想为变量中的每个字段设置监视函数,而是在监视中执行以下操作:

ignore: "template.variables.isSelected"

【问题讨论】:

  • 我不认为这是可能的,而且通常不是一个好主意,将持久化的数据与临时 UI 状态混合。如果您能承受重构的痛苦,您可以将 isSelected 存储在不被监视的单独结构中吗?它可以是一个与“变量”具有相同索引的数组,也可以是某种以名称为键的映射。
  • api 使用参数白名单,所以如果我尝试持久化 isSelected 字段并不重要,api 会将其删除。我考虑过创建一个不包含 isSelected 字段的计算属性来观察,但忽略单个字段似乎有很多开销。我希望有一种更简单的方法来做到这一点。
  • 有两种方法可以解决这个问题:计算时去掉忽略或单独列出您正在查看的所有属性:watch: { 'template.a' {}, 'template.b': {}} 省略您不想要的属性。另一种选择是使用handler(newVal, oldVal) { const diffs = getDiffs(newVal, oldVal){}},如果需要,getDiffs 可以是递归的。没有简单的方法,它还很大程度上取决于数据的结构和大小。在像您这样的情况下,巧妙地使用 lodash 有很大帮助,但大多数此类问题都可以通过健全的数据架构解决。
  • 从您的描述和您显示的数据来看,您应该使用已删除的计算。除非我们谈论的是数万或记录以上,否则开销可以忽略不计。或者,让我这样说:深度观察的开销远高于克隆和删除一些属性的开销。

标签: javascript vue.js


【解决方案1】:

您无法获得突变对象的旧值,因此我认为创建如下temp(save old data) 的一些辅助数据将帮助您解决问题。然后检查新旧数据....

var app = new Vue({
el: "#app",
data:{
  a: 1,
  template: {
    name: "Template",
    id: 1,
    variables: [
      {
        name: "v1",
        color: "#fff",
        group: 1,
        isSelected: true
      },
      {
        name: "v2",
        color: "#fff",
        group: 3,
        isSelected: false
      }
    ]
  },
  temp: {}
},
mounted: function() {
// this.template.variables[0].isSelected = false;
 this.temp = JSON.parse(JSON.stringify(this.template));
 this.$set(this.template.variables[0],"isSelected", 222);
 
},
watch : {
 template: {
   handler: function(changeVal) {
     var flag = true;
     for(var i in changeVal.variables) {
       if(changeVal.variables[i].isSelected != this.temp.variables[i].isSelected) {
         flag = false;
       }
     }
     this.temp = JSON.parse(JSON.stringify(this.template)); // assign changed data as old data again for next process
     if(flag) console.log("saveData");// this.save();
     else console.log("notsave");
   },
   deep: true
 }
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-19
    • 2019-10-27
    • 1970-01-01
    • 2017-11-29
    • 2018-08-13
    • 2018-07-12
    • 2021-10-01
    • 2018-03-12
    相关资源
    最近更新 更多