我开始了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的新手,所以我完全不知道如何修复它。有人知道如何(请解释为什么)解决这个问题吗?
除上述问题外,如有下列问题:
如果props值不是必需的,因此不总是返回,则传递的数据将返回undefined(而不是空)。这可能会混乱<select>默认值,我通过检查是否在beforeMount()设置的值来解决它(如果没有设置它)如下:
JS:
export default {
name: 'user_register',
data: () => ({
oldDobMonthMutated: this.oldDobMonth,
}),
props: [
'oldDobMonth',
'dobMonths', //Used for the select loop
],
beforeMount() {
if (!this.oldDobMonth) {
this.oldDobMonthMutated = '';
} else {
this.oldDobMonthMutated = this.oldDobMonth
}
}
}
Html:
<select v-model="oldDobMonthMutated" id="dob_months" name="dob_month">
<option selected="selected" disabled="disabled" hidden="hidden" value="">
Select Month
</option>
<option v-for="dobMonth in dobMonths"
:key="dobMonth.dob_month_slug"
:value="dobMonth.dob_month_slug">
{{ dobMonth.dob_month_name }}
</option>
</select>
再加上最好的答案,
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。如果未定义,则解析错误。
根据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来呈现模板,这样就可以在组件中保证列表道具的安全。
这与这样一个事实有关:在Vue 2中,局部变异道具被认为是一种反模式
你现在应该做的是,如果你想在本地改变一个道具,在你的数据中声明一个字段,使用props值作为它的初始值,然后改变副本:
Vue.component('task', {
template: '#task-template',
props: ['list'],
data: function () {
return {
mutableList: JSON.parse(this.list);
}
}
});
你可以在Vue.js官方指南上阅读更多相关内容
注1:请注意,您的道具和数据不应使用相同的名称,即:
data: function () { return { list: JSON.parse(this.list) } } // WRONG!!
注2:因为我觉得有一些关于道具和反应性的困惑,我建议你看看这个帖子