【问题标题】:Can i change component prop variable binded to another variable in VueJS我可以更改绑定到 VueJS 中另一个变量的组件道具变量吗
【发布时间】:2019-07-16 16:01:19
【问题描述】:
我开始学习 vuejs,想用 vue 中的组件制作一个简单的“喜欢”项目。我做了两个按钮(喜欢和不喜欢),每个按钮都有单独的计数器。直到现在一切都很好。
现在,我想在下面显示这些计数器的总和。为此,我需要在组件外部将这两个变量彼此相邻,因此我尝试将它们的值与外部变量绑定。但是外部变量没有改变!并且还在控制台中说:
[Vue 警告]:避免直接改变 prop,因为每当父组件重新渲染时,该值都会被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“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>
【问题讨论】:
标签:
javascript
vue.js
components
【解决方案1】:
对于您的情况,您可以简单地使用.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>
【解决方案2】:
真正的无法实现双向绑定,但子级可以向父级发出带有所需信息的事件,后者可以更新绑定变量。
从 2.3.0 开始,Vue 有一个特殊的 .sync modifier 可以做到这一点,这是你使用 .sync 修饰符修改后的 sn-p。请注意,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>