我开始学习vuejs,并希望使用vue中的组件创建一个简单的“ like”项目。我做了两个按钮(喜欢和不喜欢),每个按钮都有单独的计数器。到现在为止,一切都还不错。 现在,我想在下面显示这些计数器的总和。为此,我需要在组件外部将这两个变量彼此相邻,因此我尝试将其值与外部变量绑定。但是外部变量没有改变!并在控制台中说:
[Vue警告]:避免直接更改道具,因为每当父组件重新渲染时,该值就会被覆盖。而是使用基于属性值的数据或计算属性。道具被突变:“ lval” 在--->
中找到
查看我的代码:
Vue.component('like',{
template: '#like' ,
props: ['lval','lname','lstep','lclass'],
methods:{
changeCounter : function(step){
this.lval += parseInt(step);
}
}
});
new Vue({
el: '#app',
data:{
counterlike: 0,
counterdislike: 0
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<like lname="Like" lstep="1" :lval="counterlike" lclass="btn-success"></like>
<like lname="Dislike" lstep="-1" :lval="counterdislike" lclass="btn-danger"></like>
<br>
{{ counterlike + counterdislike }}
</div>
<template id="like">
<button :class="['btn',lclass]" @click="changeCounter(lstep)" >{{ lname + ' ' + lval }}</button>
</template>
答案 0 :(得分:0)
道具不能直接突变是有原因的,这种方式使信息具有单向流动,从父母到孩子,而不是相反。
答案 1 :(得分:0)
True 不能实现双向绑定,但是子级可以向父级发出带有所需信息的事件,而后者可以更新绑定变量。
从2.3.0版本开始,Vue具有特殊的.sync
modifier来做到这一点,这是使用.sync
修饰符修改的代码段。请注意,changeCounter
方法不会直接更改lval
,而是会发出事件。
这里
Vue.config.productionTip = false;
Vue.component('like', {
template: '#like',
props: ['lval', 'lname', 'lstep', 'lclass'],
methods: {
changeCounter: function(step) {
const newlval = this.lval + parseInt(step);
this.$emit('update:lval', newlval);
}
}
});
new Vue({
el: '#app',
data: {
counterlike: 0,
counterdislike: 0
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<like lname="Like" lstep="1" :lval.sync="counterlike" lclass="btn-success"></like>
<like lname="Dislike" lstep="-1" :lval.sync="counterdislike" lclass="btn-danger"></like>
<br> {{ counterlike + counterdislike }}
</div>
<template id="like">
<button :class="['btn',lclass]" @click="changeCounter(lstep)" >{{ lname + ' ' + lval }}</button>
</template>
答案 2 :(得分:0)
根据您的情况,您可以简单地使用.sync
修饰符来避免直接更改道具。同步修饰符表示您的道具接收者组件(子代)从父级接收道具数据,并在父级必须更改传递的值时生成一个事件。
父组件应将prop与'.sync'修饰符绑定,这意味着对带有更新的子事件进行自动订阅。
您可以阅读here
这样,您的代码可以正常工作
Vue.component('like',{
template: '#like' ,
props: ['lval','lname','lstep','lclass'],
methods:{
changeCounter : function(step){
this.$emit('update:lval', this.lval + parseInt(step));
}
}
});
new Vue({
el: '#app',
data:{
counterlike: 0,
counterdislike: 0
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<like lname="Like" lstep="1" :lval.sync="counterlike" lclass="btn-success"></like>
<like lname="Dislike" lstep="-1" :lval.sync="counterdislike" lclass="btn-danger"></like>
<br>
{{ counterlike + counterdislike }}
</div>
<template id="like">
<button :class="['btn',lclass]" @click="changeCounter(lstep)" >{{ lname + ' ' + lval }}</button>
</template>