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

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

更新

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

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

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

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


当前回答

手表功能应该放在子组件中。没有父母。

其他回答

如果myProp是一个对象,通常不可以更改。所以,手表永远不会被触发。为什么myProp不被改变的原因是你在大多数情况下只设置myProp的一些键。myProp本身仍然是一个。 试着看myProp的道具,比如“myProp”。A "应该有用。

如果你的道具myProp有嵌套项,这些嵌套项不会是反应性的,所以你需要使用像lodash deepClone这样的东西:

<child :myProp.sync="_.deepClone(myProp)"></child>

就这样,不需要监视或其他任何东西。

我认为在大多数情况下,Vue会在道具变化时更新组件的DOM。

如果这是你的情况,那么你可以使用beforeUpdate()或updated()钩子(docs)来观察道具。

如果你只对新val感兴趣而不需要旧val,你可以这样做

new Vue({ el: '#app', data: { text: '' }, components: { 'child': { template: `<p>{{ myprop }}</p>`, props: ['myprop'], beforeUpdate() { console.log(this.myprop) }, updated() { console.log(this.myprop) } } } }); <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <child :myprop="text"></child> <input v-model="text" placeholder="Type here to view prop changes" style="width:20em"> </div>

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

父组件- 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。

我希望这能有所帮助。

我使用道具和变量计算属性,如果我需要创建逻辑后接收更改

export default {
name: 'getObjectDetail',
filters: {},
components: {},
props: {
    objectDetail: {
      type: Object,
      required: true
    }
},
computed: {
    _objectDetail: {
        let value = false
        ...

        if (someValidation)
        ...
    }
}