避免直接改变道具,因为每当父组件重新渲染时,该值都会被覆盖
Posted
技术标签:
【中文标题】避免直接改变道具,因为每当父组件重新渲染时,该值都会被覆盖【英文标题】:Getting avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders 【发布时间】:2017-05-04 02:27:30 【问题描述】:我是 vuejs 的新手,我正在尝试将 active 数据同步到父级,但出现错误
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>
谁能帮我解决这个问题
【问题讨论】:
【参考方案1】:正如错误提示的那样,您正在尝试更改其中一个道具active
。
正在变异的道具:“活跃”(在组件中找到)
由于 props 是从 parent 动态发送的,因此只要 parent 更改它们,它们就会更改,如果您在 child 中也更改它们,则会发生冲突,这就是您收到此错误的原因。
和documentation一样:
父子组件关系可以概括为props down,events up。父级通过 props 向下传递数据给子级,子级通过事件向父级发送消息。
因此,正确的方法是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>
【讨论】:
这个解释比文档清楚多了。 VueJS 只是通过不允许属性值向上突变来实现 MVVM 范式。【参考方案2】:我希望这是版本问题。请显示您的 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>aplan.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>
【讨论】:
以上是关于避免直接改变道具,因为每当父组件重新渲染时,该值都会被覆盖的主要内容,如果未能解决你的问题,请参考以下文章