在VueJs 2.0文档中,我找不到任何可以监听道具变化的钩子。

VueJs有这样的钩子像onpropsupdate()或类似的吗?

更新

正如@wostex建议的那样,我试着观察我的财产,但没有任何变化。然后我意识到我遇到了一个特殊的情况:

<template>
    <child :my-prop="myProp"></child>
</template>

<script>
   export default {
      props: ['myProp']
   }
</script>

我将父组件接收到的myProp传递给子组件。然后手表:{myProp:…不起作用。


当前回答

在我的情况下,我没有得到任何信息,也无法检索信息。一定要在手表内部使用试扣

我的情况

setup(props, { emit, attrs, slots, expose }) {
...
....
..... 
}
.....
  watch: {
    isModalActive: function () {
      console.log('action:: ', this.props.isModalActive) // here cause error undefined and no error information on my inspect element dunno why
    }
  },

所以当我试图安慰别人的时候

  watch: {
    isModalActive: function () {
      console.log('action:: ') // this work and printed
      console.log('action:: ', this.props.isModalActive)
    }
  },

其他回答

对一些用例的有趣观察。

如果您通过道具从存储中监视数据项,并且在同一存储中多次更改数据项,则不会监视该数据项。

但是,如果您将数据项更改分离为相同突变的多个调用,它将被监视。

This code will NOT trigger the watcher: // Somewhere in the code: this.$store.commit('changeWatchedDataItem'); // In the 'changeWatchedDataItem' mutation: state.dataItem = false; state.dataItem = true; This code WILL trigger the watcher at each mutation: // Somewhere in the code: this.$store.commit('changeWatchedDataItem', true); this.$store.commit('changeWatchedDataItem', false); // In the 'changeWatchedDataItem' mutation: changeWatchedDataItem(state, newValue) { state.dataItem = newValue; }

在我的情况下,我需要一个解决方案,任何时候任何道具都会改变,我需要再次解析我的数据。我厌倦了为我所有的道具制作分离的观察者,所以我用了这个:

  watch: {
    $props: {
      handler() {
        this.parseData();
      },
      deep: true,
      immediate: true,
    },
  },

从这个例子中得到的关键点是使用deep: true,这样它不仅监视$props,而且还监视它的嵌套值,例如props. myprop

你可以在这里了解更多关于这款扩展手表的选择:https://v2.vuejs.org/v2/api/#vm-watch

你可以使用观察模式来检测变化:

在原子级别上做所有事情。首先检查watch方法本身是否被调用通过安慰内部的东西。一旦确定要调用手表,就用您的业务逻辑将其粉碎。

watch: { 
  myProp: function() {
   console.log('Prop changed')
  }
}

@JoeSchr有答案。如果你不想要深度,还有另一种方法:true

 mounted() {
    this.yourMethod();
    // re-render any time a prop changes
    Object.keys(this.$options.props).forEach(key => {
      this.$watch(key, this.yourMethod);
    });
  },

你需要理解,你拥有的组件层次结构和你如何传递道具,你的情况肯定是特殊的,通常不会被开发人员遇到。

父组件- myprop ->子组件- myprop ->孙子 组件

如果myProp在父组件中被更改,它也会反映在子组件中。

如果myProp在子组件中被改变,它也会反映在孙子组件中。

因此,如果myProp在父组件中被更改,那么它将反映在孙辈组件中。(到目前为止还不错)。

因此,在层次结构中,你不需要做任何事情,道具将具有固有的反应性。

现在说到等级的上升

如果myProp在孙子组件中被更改,它将不会反映在子组件中。你必须在child中使用.sync修饰符,并从grandChild组件中触发事件。

如果myProp在子组件中被更改,它将不会反映在父组件中。你必须在父组件中使用.sync修饰符,并从子组件中触发事件。

如果myProp在grandChild组件中被更改,它将不会反映在父组件中(显然)。你必须使用.sync修饰符子组件并从孙子组件发出事件,然后观察子组件中的道具并在更改时发出事件,该事件由使用.sync修饰符的父组件监听。

让我们看一些代码以避免混淆

Parent.vue

<template>
    <div>
    <child :myProp.sync="myProp"></child>
    <input v-model="myProp"/>
    <p>{{myProp}}</p>
</div>
</template>

<script>

    import child from './Child.vue'

    export default{
        data(){
            return{
                myProp:"hello"
            }
        },
        components:{
            child
        }
    }
</script>

<style scoped>
</style>

Child.vue

<template>
<div>   <grand-child :myProp.sync="myProp"></grand-child>
    <p>{{myProp}}</p>
</div>

</template>

<script>
    import grandChild from './Grandchild.vue'

    export default{
        components:{
            grandChild
        },
        props:['myProp'],
        watch:{
            'myProp'(){
                this.$emit('update:myProp',this.myProp)

            }
        }
    }
</script>

<style>

</style>

Grandchild.vue

<template>
    <div><p>{{myProp}}</p>
    <input v-model="myProp" @input="changed"/>
    </div>
</template>

<script>
    export default{
        props:['myProp'],
        methods:{
            changed(event){
                this.$emit('update:myProp',this.myProp)
            }
        }
    }
</script>

<style>

</style>

但在这之后,你会情不自禁地注意到vue说的尖叫警告

'避免直接改变prop,因为该值将被覆盖 每当父组件重新渲染时。

正如我之前提到的,大多数开发者不会遇到这个问题,因为这是一个反模式。这就是为什么你会得到这个警告。

但是为了解决你的问题(根据你的设计)。我相信你已经做了上面的工作(诚实地说,黑客)。我仍然建议你应该重新考虑你的设计,让它更不容易出现bug。

我希望这能有所帮助。