避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖

时间:2016-12-19 04:31:04

标签: javascript vue.js

我是vuejs的新手,我正在尝试将有效数据同步到父级,但收到错误

  

vue.js:523 [Vue警告]:避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖。而是根据prop的值使用数据或计算属性。支持变异:“活跃”   (在组件中找到)

我的Vuejs代码如下

<div id="app">
    <pre>
        {{$data}}
    </pre>
    <div v-for="plan in plans">
        <plan :plan="plan" :active.sync="active"></plan>
    </div>
</div>
<template id="mytemplate">
    <div>
        {{$data}}
        <span>{{plan.name}}</span>
        <span>{{plan.price}}</span>
        <button @click="setActivePlan">upgrade</button>
    </div>
</template>

<script src="vue.js"></script>
<script>
    new Vue({
        el: "#app",

        data: {
            active:this.active,
            plans: [
                {name: 'Diamond', price: '1000'},
                {name: 'Gold', price: '500'},
                {name: 'Silver', price: '250'},
                {name: 'Free', price: '0'}
            ]
        },
        components: {
            plan: {
                template: "#mytemplate",
                props: ['plan', 'active'],
                methods: {
                    setActivePlan: function () {
                        this.active = this.plan
                    }
                }
            }
        }

    });
</script>

任何人都可以帮我解决这个问题

2 个答案:

答案 0 :(得分:5)

如错误所示,您正在尝试更改其中一个道具active

  

支持变异:“活跃”(在组件中找到)

由于道具是从父母动态发送的,所以当父母改变道具时,它们会发生变化,如果你在孩子身上也改变了道具,那么就会发生冲突,这就是你得到这个错误的原因。

documentation

相同
  

父子组件关系可以概括为道具向下,事件向上。父级通过道具将数据传递给子级,子级通过事件向父级发送消息。

所以正确的方法是emit一个事件,它将调用父项中的方法,并在父项中更改变量active。以下是代码更改:

<script src="vue.js"></script>
<script>
    new Vue({
        el: "#app",

        data: {
            active:this.active,
            plans: [
                {name: 'Diamond', price: '1000'},
                {name: 'Gold', price: '500'},
                {name: 'Silver', price: '250'},
                {name: 'Free', price: '0'}
            ]
        },
        methods: {
           setActivePlan: function (plan) {
              this.active = plan
           }
        } 
        components: {
            plan: {
                template: "#mytemplate",
                props: ['plan', 'active'],
                methods: {
                    setActivePlan: function () {
                        this.$emit('setActivePlan', this.plan)
                    }
                }
            }
        }

    });
</script>

答案 1 :(得分:1)

我希望这是版本问题。请显示您的VUEJS版本,否则从下面的代码中获取版本。

<div id="app">
    <pre>
    {{$data |  json}}
    </pre>
        <div v-for="plan in plans">
            <plan :plan="plan" :active.sync="active"></plan>
        </div>
    </div>
    <template id="mytemplate">
        <div>
            <span>{{plan.name}}</span>
            <span>{{plan.price}}</span>
            <span>a{{plan.active}}</span>
            <button @click="setActivePlan">upgrade</button>
        </div>
    </template>

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.25/vue.js"></script>
    <script>
        new Vue({
            el: "#app",

            data: {
                plans: [
                    {name: 'Diamond', price: '1000'},
                    {name: 'Gold', price: '500'},
                    {name: 'Silver', price: '250'},
                    {name: 'Free', price: '0'}
                ],
                active:{

                }
            },
            components: {
                plan: {
                    template: "#mytemplate",
                    props: ['plan', 'active'],
                    methods: {
                        setActivePlan: function () {
                            this.active = this.plan
                        }
                    }
                }
            }

        });
    </script>