【问题标题】:Cannot watch a cloned value无法查看克隆值
【发布时间】:2022-01-19 20:16:33
【问题描述】:

这是我的问题的最小示例。我试图在 SO 上找到类似的问题,但没有找到任何东西,如果它是重复的,请见谅。

App.vue

 <template>
  <div>
    <SubComponent v-model="myValue" />
    <SubComponent v-model="myClonedValue" />
  </div>
</template>

<script>
import SubComponent from "./components/SubComponent";

export default {
  components: { SubComponent },
  data: function () {
    return {
      myValue: {
        foo: 45,
        bar: 38,
      },
    };
  },
  computed: {
    myClonedValue: function () {
      return { ...this.myValue };
    },
  },
  watch: {
    "myValue.foo": function (val, oldVal) {
      console.log(val, oldVal);
    },
    /* This Doesn't work either

    "myClonedValue.foo": function (val, oldVal) {
      console.log(val, oldVal);
    },
    */
    myClonedValue: {
      handler: function (val, oldVal) {
        console.log(val, oldVal);
      },
      deep: true,
    },
  },
};
</script>

子组件

<template>
  <input v-model="value.foo" type="text" />
</template>

<script>
export default {
  name: "SubComponent",
  props: {
    msg: String,
    value: Object,
  },
};
</script>

问题

在我的主要用例中,我有一个对象,只有在确认更改后才想修改它。所以我用计算属性克隆它的值,出于某种原因,我需要观察一些值是否被修改。我的问题在这里,您可以在此 CodeSandBox 上在线查看 CodeSandBox project 一旦我克隆数据值,VueJS 就不会检测到任何变化。如果您更改我示例的第二个输入,则不会发生任何事情。

我该如何解决这个问题?

【问题讨论】:

  • 观看:{ myValue: { handler: function(newValue) { console.log(newValue.foo) }, deep: true } }

标签: javascript vue.js


【解决方案1】:

计算属性不只是克隆一次原始值。它创建一个反应绑定并在每次原始值更改时重新计算。所以你需要一种不同的方法。

将 clonedValue 设为常规数据属性,并在 created 或 Mounted 生命周期挂钩中为其分配一个值。然后您将能够以原始价值观看它。而且(我认为)更重要的是,现在您将能够独立修改原始值和克隆值。

data: {
    myValue: { foo: 1, bar: 2 },
    clonedValue: {}
},
created() {
    this.clonedValue = {...this.myValue}
}

【讨论】:

  • 我认为它在我的主要用例中不起作用,因为我克隆的值是一个在数组中的对象,它是一个列表。我的意思是,用户看到一个元素列表并选择一个并可以修改它。
  • 您可以在用户选择一个元素而不是 created() 时创建一个副本。这行得通吗?
  • 我认为它会起作用。你能告诉我在我的最小示例中我需要做的改变吗?在我的实际项目中,我以类似的方式解决了我的问题。
  • 我认为我上面提供的代码足以修复您的最小示例。删除计算属性,将 myClonedValue 添加到数据并将 myValue 复制到某处(例如在创建中)。观察者应该在这两个属性上都能正常工作。
【解决方案2】:

您可以使用深度观察者来实现这一点,但您可能必须自己检查内部键

watch: {
    myValue: {
        handler (val, oldVal) {
            if(val.prop !== oldVal.prop){
               // do something
            }
        },
        deep: true,
    },
},

【讨论】:

  • 欢迎使用 Stack Overflow Alisson,我认为它不能解决我的问题。一旦 myClonedValue 从第二个输入更改,我想检测更改
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2020-03-24
相关资源
最近更新 更多