我开始了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'],
    computed: {
      middleData() {
        return this.list
      }
    },
    watch: {
      list(newVal, oldVal) {
        console.log(newVal)
        this.newList = newVal
      }
    },
    data() {
      return {
        newList: {}
      }
    }
});
new Vue({
    el: '.container'
})

也许这个能满足你的需要。

其他回答

如果您正在使用Lodash,您可以在返回之前克隆道具。如果同时修改父节点和子节点上的道具,则此模式非常有用。

假设我们在组件网格上有道具列表。

在父组件中

<grid :list.sync="list"></grid>

在子组件中

props: ['list'],
methods:{
    doSomethingOnClick(entry){
        let modifiedList = _.clone(this.list)
        modifiedList = _.uniq(modifiedList) // Removes duplicates
        this.$emit('update:list', modifiedList)
    }
}

再加上最好的答案,

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。如果未定义,则解析错误。

是的!, ve2中的属性突变是一种反模式。但是… 只要打破规则,用其他规则,继续前进! 您需要做的是在父作用域的组件属性中添加.sync修饰符。

<your-awesome-components :custom-attribute-as-prob.sync="value" />

我个人总是建议,如果你需要改变道具,首先将它们传递给计算属性,然后从那里返回,然后就可以很容易地改变道具,即使在那你也可以跟踪道具的突变,如果它们是从另一个组件中突变的,或者我们也可以观察。

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    computed: {
      middleData() {
        return this.list
      }
    },
    watch: {
      list(newVal, oldVal) {
        console.log(newVal)
        this.newList = newVal
      }
    },
    data() {
      return {
        newList: {}
      }
    }
});
new Vue({
    el: '.container'
})

也许这个能满足你的需要。