我在试着理解如何正确地观察一些道具的变化。 我有一个父组件(。Vue文件),从ajax调用接收数据,把数据放在一个对象中,并使用它来通过v-for指令渲染一些子组件,下面是我的实现的简化:

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

... 然后在<script>标签内:

 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对象是这样的:

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

现在,在我的孩子“播放器”组件中,我试图观察任何项目的属性变化,我使用:

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

这是可行的,但对我来说似乎有点棘手,我想知道这是否是正确的方法。我的目标是每次道具改变或myArray获得新元素或现有元素中的一些变化时执行一些操作。任何建议都将不胜感激。


当前回答

这些答案对我来说都没用。实际上,如果你想观察嵌套的数据与组件被多次调用。所以他们被称为不同的道具来识别他们。 例如<MyComponent chart="chart1"/> <MyComponent chart="chart2"/> 我的解决方法是创建一个额外的vuex状态变量,我手动更新它以指向上次更新的属性。

这是一台Vuex。Ts实现示例:

export default new Vuex.Store({
    state: {
        hovEpacTduList: {},  // a json of arrays to be shared by different components, 
                             // for example  hovEpacTduList["chart1"]=[2,6,9]
        hovEpacTduListChangeForChart: "chart1"  // to watch for latest update, 
                                                // here to access "chart1" update 
   },
   mutations: {
        setHovEpacTduList: (state, payload) => {
            state.hovEpacTduListChangeForChart = payload.chart // we will watch hovEpacTduListChangeForChart
            state.hovEpacTduList[payload.chart] = payload.list // instead of hovEpacTduList, which vuex cannot watch
        },
}

在任何Component函数上更新存储:

    const payload = {chart:"chart1", list: [4,6,3]}
    this.$store.commit('setHovEpacTduList', payload);

现在对任何组件进行更新:

    computed: {
        hovEpacTduListChangeForChart() {
            return this.$store.state.hovEpacTduListChangeForChart;
        }
    },
    watch: {
        hovEpacTduListChangeForChart(chart) {
            if (chart === this.chart)  // the component was created with chart as a prop <MyComponent chart="chart1"/> 
                console.log("Update! for", chart, this.$store.state.hovEpacTduList[chart]);
        },
    },

其他回答

下面是一种为嵌套属性编写观察者的方法:

    new Vue({
        ...allYourOtherStuff,
        watch: {
            ['foo.bar'](newValue, oldValue) {
                // Do stuff here
            }
        }
    });

你甚至可以对异步观察者使用这个语法:

    new Vue({
        ...allYourOtherStuff,
        watch: {
            async ['foo.bar'](newValue, oldValue) {
                // Do stuff here
            }
        }
    });

你可以使用深层观察者:

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

现在它将检测对项目数组中对象的任何更改以及对数组本身的添加(当与Vue.set一起使用时)。这是一个JSFiddle: http://jsfiddle.net/je2rw3rs/

EDIT

如果你不想观察顶层对象的每一个变化,只是想要一个不那么尴尬的语法来直接观察嵌套对象,你可以简单地观察一个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/

这里没有提到,但是如果要扩展Vue类,也可以使用Vue -property-decorator模式。

import { Watch, Vue } from 'vue-property-decorator';

export default class SomeClass extends Vue {
   ...

   @Watch('item.someOtherProp')
   someOtherPropChange(newVal, oldVal) {
      // do something
   }

   ...
}

这些答案对我来说都没用。实际上,如果你想观察嵌套的数据与组件被多次调用。所以他们被称为不同的道具来识别他们。 例如<MyComponent chart="chart1"/> <MyComponent chart="chart2"/> 我的解决方法是创建一个额外的vuex状态变量,我手动更新它以指向上次更新的属性。

这是一台Vuex。Ts实现示例:

export default new Vuex.Store({
    state: {
        hovEpacTduList: {},  // a json of arrays to be shared by different components, 
                             // for example  hovEpacTduList["chart1"]=[2,6,9]
        hovEpacTduListChangeForChart: "chart1"  // to watch for latest update, 
                                                // here to access "chart1" update 
   },
   mutations: {
        setHovEpacTduList: (state, payload) => {
            state.hovEpacTduListChangeForChart = payload.chart // we will watch hovEpacTduListChangeForChart
            state.hovEpacTduList[payload.chart] = payload.list // instead of hovEpacTduList, which vuex cannot watch
        },
}

在任何Component函数上更新存储:

    const payload = {chart:"chart1", list: [4,6,3]}
    this.$store.commit('setHovEpacTduList', payload);

现在对任何组件进行更新:

    computed: {
        hovEpacTduListChangeForChart() {
            return this.$store.state.hovEpacTduListChangeForChart;
        }
    },
    watch: {
        hovEpacTduListChangeForChart(chart) {
            if (chart === this.chart)  // the component was created with chart as a prop <MyComponent chart="chart1"/> 
                console.log("Update! for", chart, this.$store.state.hovEpacTduList[chart]);
        },
    },

我个人更喜欢这种简洁的实现方式:

watch: {
  myVariable: {
     handler(newVal, oldVal){  // here having access to the new and old value
     // do stuff
       console.log(newVal, oldVal);
     },
     deep: true,
     /*
         Also very important the immediate in case you need it,
         the callback will be called immediately after the start
         of the observation
     */
     immediate: true 

  }
}