2017-05-30 11 views
0

このような質問はたくさんありますが、これは少し異なります。私はreactivity in depthでAA見ていたと私は、件名に公正な理解を持っていると思う、私も理解できない一つのことはこれです:vueで監視対象が更新されないのはなぜですか?

TL;

DRなぜcurrentValue = Object.assign=({}, currentValue, initValue)で初期化時に監視されるプロパティ・レジスタの変更を行います直接割り当てではありませんcurrentValue = initValue;

私は、モデルのscoreRules

this.$data.scoreRules = initScoreRules;

を(使用して再初期化、mountedフックで私VUEコンポーネント

のモデルに登録されたオブジェクト、scoreRulesを持って

  1. initScoreRulesは小道具として渡されますが、私はそれをこの質問の目的のためにローカル変数 を以下に示します)。

  2. 腕時計scoreRules変更とログは、オブジェクトが変更されたときに "スコアが変更されました"。

このコードは、このシナリオ今

new Vue({ 
 
    el: '#app', 
 
    data() { 
 
    return { 
 
     scoreRules: { 
 
     type: "number", 
 
     minimum: null, 
 
     maximum: null 
 
     } 
 
    } 
 
    }, 
 
    mounted() { 
 
    let initScoreRules = {type: "number"}; 
 
    this.$data.scoreRules = initScoreRules; 
 
    this.$watch('scoreRules',()=>{console.log("score has been changed")}, {deep: true}); 
 
    } 
 
});
<html> 
 

 
<head> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.js"></script> 
 
</head> 
 

 
<body> 
 
    <div id="app"> 
 
    <span>Minimum score</span> 
 
    <input type="number" name="minimumScore" v-model.number="scoreRules.minimum" /> 
 
</body> 
 

 
</html>

を示し、私は入力に何かを入力すると、時計はこの変更をキャッチしていないと何もコンソールに記録されません。

私は今、変化が登録され、出力がコンソールに記録され this.$data.scoreRules = Object.assign({}, this.$data.scoreRules, initScoreRules);

new Vue({ 
 
    el: '#app2', 
 
    data() { 
 
    return { 
 
     scoreRules: { 
 
     minimum: null 
 
     } 
 
    } 
 
    }, 
 
    mounted() { 
 
    let initScoreRules = {}; 
 
    this.$data.scoreRules = Object.assign({}, this.$data.scoreRules, initScoreRules); 
 
    this.$watch('scoreRules',() => { 
 
     console.log("score has been changed") 
 
    }, { 
 
     deep: true 
 
    }); 
 
    } 
 
});
<html> 
 

 
<head> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.js"></script> 
 
</head> 
 

 
<body> 
 
    <div id="app2"> 
 
    <span>Minimum score</span> 
 
    <input type="number" v-model.number="scoreRules.minimum" /> 
 
    </div> 
 
</body> 
 

 
</html>

を使用してscoreRulesを再初期化した場合。どうして?私はそれがJS自体の内部と関係があると考えていますが、正確な方法はわかりません。

+2

オブジェクトが参照型です。これは、 '='を使って既存のものを指すのではなく、オブジェクトを 'Object.assign'でクローンする必要がある理由です。新しいオブジェクトを作成すると、オブジェクトとそのプロパティの反応環境を設定することができます。 – wostex

+0

私は参照してください。 '= 'で直接割り当てを行うと、非反応性のオブジェクトが指し示され、そのために変更されたものは登録されません。今明らかになっているようだ。ありがとうございました。 –

答えて

1

初期オブジェクトには、プロパティminimummaximumが含まれていました。その後、mountedでは、あなたがこれを行う:

let initScoreRules = {type: "number"}; 
this.$data.scoreRules = initScoreRules; 

を今scoreRulesオブジェクトは、それらの性質を持っていないことを意味します。

Vueのはどちらか一方のみである特性の変化を観察することができます:data()で事前に定義された

  • (あなたがしたが、その後mountedにアンでした)
  • Vue.set()/this.$set()
  • 存在とセットリアクティブプロパティに割り当てられているオブジェクトに適用されます。

最後の点は、2番目の例では、作業の理由の説明もある。ここでは、基本的にあなたがこれ(それが邪魔なのでObject.assign冗長性をアウトのleavin)ん:

this.$data.scoreRules = { minimum: null }; 

このプロパティはになります反応性である。

はもっとここで読む:

https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

+1

ありがとう@Linus。完璧に集計されています。 –

関連する問題