2017-02-09 68 views
74

我想了解如何正確觀察一些支柱變化。 我有一個從ajax調用接收數據的父組件(.vue文件),將數據放入一個對象中,並通過v-for指令呈現某個子組件,在我的實現簡化下面:Vue.js - 如何正確觀察嵌套屬性

<template> 
    <div> 
     <player v-for="(item, key, index) in players" 
      :item="item" 
      :index="index" 
      :key="key""> 
     </player> 
    </div> 
</template> 

...然後裏面的 「腳本」 標籤:

data(){ 
    return { 
     players: {} 
}, 
created(){ 
     let self = this; 
     this.$http.get('../serv/config/player.php').then((response) => { 
      let pls = response.body; 
      for (let p in pls) { 
       self.$set(self.players, p, pls[p]); 
      } 
    }); 
} 

項目的對象是這樣的:現在

item:{ 
    prop: value, 
    someOtherProp: { 
     nestedProp: nestedValue, 
     myArray: [{type: "a", num: 1},{type: "b" num: 6} ...] 
    }, 
} 

,我的孩子裏面的 「玩家」 COMPONE NT我試圖觀看任何項目的屬性變化,我用:

... 
watch:{ 
    'item.someOtherProp'(newVal){ 
     //to work with changes in "myArray" 
    }, 
    'item.prop'(newVal){ 
     //to work with changes in prop 
    } 
} 

它的工作原理,但它似乎有點棘手給我,我想知道,這是做正確的方式。我的目標是執行某些操作時都「託」的變化或myArray的獲取新的元素或者將現有的 任何建議將appriciated

+0

只要使用 ' 「item.someOtherProp」:功能(的newval,OLDVAL){'如@Ron建議。 – Reiner

+1

@Reiner這正是他想要避免的問題;使用ES5語法也是一樣的。實際上在觀看計算時沒有任何額外的開銷,並且在各種情況下這是一種有用的技術。 –

回答

106

裏面的一些變化,您可以使用一個deep watcher

watch{ 
    item: { 
    handler(val){ 
     // do stuff 
    }, 
    deep: true 
    } 
} 

這現在將檢測item陣列中對象的任何更改,並添加到陣列本身(與Vue.set一起使用時)。這裏有一個的jsfiddle:http://jsfiddle.net/je2rw3rs/

編輯

如果你不想看的頂級對象上的每一個變化,只想直接觀看嵌套對象方便些語法,你可以簡單地看一個computed代替:

var vm = new Vue({ 
    el: '#app', 
    computed: { 
    foo() { 
     return this.item.foo; 
    } 
    }, 
    watch: { 
    foo() { 
     console.log('Foo Changed!'); 
    } 
    }, 
    data: { 
    item: { 
     foo: 'foo' 
    } 
    } 
}) 

這裏的的jsfiddle:http://jsfiddle.net/oa07r5fw/

+1

通過這種方式,每當任何道具有變化時,都會調用「處理程序」,我的目的是將處理程序分開以便觀察變化是發生在「prop」還是在「someOtherProp」中的myArray內 – Plastic

+4

如果您只是想觀看對特定的嵌套對象進行更改,那麼你在做什麼是好的。如果你想要一個不太笨拙的語法,你可以看一個'computed'代替:http://jsfiddle.net/c52nda7x/ –

+0

正是我在找的東西,現在看起來對我來說很邏輯:創建一個計算屬性,返回嵌套支撐並觀察它。 Tnx很多。 – Plastic

63

另一個好辦法,一個是多一點優雅如下:

watch:{ 
    'item.someOtherProp': function (newVal, oldVal){ 
     //to work with changes in someOtherProp 
    }, 
    'item.prop': function(newVal, oldVal){ 
     //to work with changes in prop 
    } 
} 

(我在comment here瞭解到這種方法從@peerbolte)

+3

方式更優雅(不只是一點點):P。這應該在Vue.js文檔中,因爲它是一個常見的用例。我一直在尋找解決方案的小時,謝謝你的回答。 – Symba

+2

@symba有趣的是,人們並沒有注意到這是OP要求避免的同樣的事情,僅僅是'ES5'語法。我們當然可以爭辯說['ES2015方法定義'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions)本身並不是很優雅,但它很實用錯過了這個問題的關鍵點,那就是如何避免包裹這個名字就是引號。我猜大多數人都在回答已經包含答案的原始問題,並且實際上正在尋找一些如你所說的沒有很好記錄的東西, –

+0

@craig_h超級有趣的一點。我原本打算好幾個小時才找到一種觀看嵌套道具的好方法。這個問題標題是我發現的最接近的問題,但我錯過了他在問題的主體中列出了引用的道具,但發現答案並不那麼優雅。我終於在另一個問題的評論中找到了引用的道具方法,並試圖創建一個問題來自我回答它作爲SO上引用的道具方法的文檔。但是這個問題恰恰是我的標題,因此我在這裏添加了答案。也許我應該創造一個新的問題。 –