我开始了https://laracasts.com/series/learning-vue-step-by-step系列。我在Vue、Laravel和AJAX的课程上停了下来,出现了这个错误:

Vue .js:2574 [Vue警告]:避免直接改变道具,因为每当父组件重新呈现时,该值将被覆盖。相反,应该使用基于道具值的数据或计算属性。道具被突变:"list"(在组件中找到)

我在main.js中有这段代码

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    created() {
        this.list = JSON.parse(this.list);
    }
});
new Vue({
    el: '.container'
})

我知道,当我覆盖列表道具时,问题是在created(),但我是Vue的新手,所以我完全不知道如何修复它。有人知道如何(请解释为什么)解决这个问题吗?


当前回答

再加上最好的答案,

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    data: function () {
        return {
            mutableList: JSON.parse(this.list);
        }
    }
});

通过数组设置道具是为了开发/原型,在生产中确保设置道具类型(https://v2.vuejs.org/v2/guide/components-props.html),并设置一个默认值,以防道具没有被父元素填充。

Vue.component('task', {
    template: '#task-template',
    props: {
      list: {
        type: String,
        default() {
          return '{}'
        }
      }
    },
    data: function () {
        return {
            mutableList: JSON.parse(this.list);
        }
    }
});

这样你至少可以在mutableList中得到一个空对象,而不是JSON。如果未定义,则解析错误。

其他回答

您需要像这样添加computed方法

component.vue

props: ['list'],
computed: {
    listJson: function(){
        return JSON.parse(this.list);
    }
}

Vue.js认为这是一个反模式。例如,声明和设置一些道具

this.propsVal = 'new Props Value'

所以为了解决这个问题,你必须从数据或Vue实例的计算属性的道具中获取一个值,就像这样:

props: ['propsVal'],
data: function() {
   return {
       propVal: this.propsVal
   };
},
methods: {
...
}

这肯定有用。

根据VueJs 2.0,您不应该改变组件内部的道具。它们只会被父母变异。因此,您应该在数据中定义不同名称的变量,并通过观察实际的道具来更新它们。 如果列表道具被父元素更改,您可以解析它并将其分配给mutableList。这里有一个完整的解决方案。

Vue.component('task', {
    template: ´<ul>
                  <li v-for="item in mutableList">
                      {{item.name}}
                  </li>
              </ul>´,
    props: ['list'],
    data: function () {
        return {
            mutableList = JSON.parse(this.list);
        }
    },
    watch:{
        list: function(){
            this.mutableList = JSON.parse(this.list);
        }
    }
});

它使用mutableelist来呈现模板,这样就可以在组件中保证列表道具的安全。

如果你想改变道具-使用对象。

<component :model="global.price"></component>

组件:

props: ['model'],
methods: {
  changeValue: function() {
    this.model.value = "new value";
  }
}

单向数据流, 根据https://v2.vuejs.org/v2/guide/components.html,该组件遵循单向 数据流, 所有的道具在子属性和父属性之间形成了一个单向的向下绑定,当父属性更新时,它将向下流到子属性,而不是相反,这可以防止子组件意外地改变父属性,这可能会使你的应用程序的数据流更难理解。

此外,每次父组件更新所有的道具 子组件中的值将被刷新为最新值。这意味着您不应该试图改变子组件中的道具。如果你这样做了,vue会在 控制台。

通常有两种情况很容易对道具进行变异: prop用于传入一个初始值;子组件希望随后将其用作本地数据属性。 道具作为需要转换的原始值传递进来。 这些用例的正确答案是: 定义一个本地数据属性,使用prop的初始值作为其初始值:

props: ['initialCounter'],
data: function () {
  return { counter: this.initialCounter }
}

定义一个计算属性,从prop的值计算:

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}