我开始了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.js的道具不能被改变,因为这被认为是Vue中的反模式。
您需要采取的方法是在组件上创建一个引用list的原始prop属性的data属性
props: ['list'],
data: () {
return {
parsedList: JSON.parse(this.list)
}
}
现在传递给组件的列表结构通过组件的data属性被引用和改变:-)
如果您希望做的不仅仅是解析列表属性,那么请使用Vue组件的computed属性。
这允许你对你的道具做出更深入的变化。
props: ['list'],
computed: {
filteredJSONList: () => {
let parsedList = JSON.parse(this.list)
let filteredList = parsedList.filter(listItem => listItem.active)
console.log(filteredList)
return filteredList
}
}
上面的示例将解析您的列表道具,并将其过滤为仅活跃的list-tems,将其记录为schnitts和giggles并返回它。
注意:数据和计算属性在模板中引用相同
<pre>{{parsedList}}</pre>
<pre>{{filteredJSONList}}</pre>
很容易认为计算属性(作为一个方法)需要被调用…它不
我想给出这个答案,这有助于避免使用大量的代码,观察者和计算属性。在某些情况下,这可能是一个很好的解决方案:
道具是用来提供单向交流的。
当你有一个带有道具的模态显示/隐藏按钮时,对我来说最好的解决方案是发出一个事件:
<button @click="$emit('close')">Close Modal</button>
然后添加监听器到模态元素:
<modal :show="show" @close="show = false"></modal>
(在这种情况下,道具显示可能是不必要的,因为你可以直接在基本模式上使用简单的v-if="show")
Vue3有一个很好的解决方案。花了好几个小时才到那里。但是效果很好。
在父模板上
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
子组件
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
template: `
<input
type="text"
:value="firstName"
@input="$emit('update:firstName',
$event.target.value)">
<input
type="text"
:value="lastName"
@input="$emit('update:lastName',
$event.target.value)">
`
})
这是唯一能双向结合的解。我喜欢前两个答案,以良好的方式使用同步和发射更新事件,并计算属性getter setter,但这是一个工作要做的,我不喜欢这么努力工作。