我正在尝试构建一个三态复选框组件。
最初,该复选框的值为null,并由indeterminate
复选框表示。
当用户单击不确定的复选框时,该值将变为true,然后单击false,然后再次为null。
到目前为止,这就是我所拥有的:
Vue.component('checkbox', {
template: '<input type="checkbox" @change="change" class="checkbox-input">',
props: ['currentSate'],
mounted: function () {
this.currentSate = null;
this.$el.indeterminate = true
},
methods: {
change: function () {
if (this.currentSate == null) {
this.currentSate = true;
this.$el.checked = true;
this.$el.indeterminate = false;
return;
}
if (this.currentSate == true) {
this.currentSate = false
this.$el.checked = false;
this.$el.indeterminate = false;
return;
}
if (this.currentSate == false) {
this.currentSate = null;
this.$el.indeterminate = true;
return;
}
this.$emit('input', this.currentSate);
}
}
});
<checkbox v-bind:current-sate="chState"></checkbox>
chState = {{chState}}
我得到的错误是:
避免直接更改prop,因为每当父组件重新渲染时,该值都会被覆盖。而是使用基于属性值的数据或计算属性。道具被突变:“ currentSate”
这怎么实现?
答案 0 :(得分:1)
出现此错误时,简而言之,您需要发出所需的值,但让父级对其进行设置,以使它向下流回该属性。
您使用return !x;
向父级发送事件,父级将绑定到^[a-zA-Z0-9\.\/#-][a-zA-Z0-9\.\/# -]*[a-zA-Z0-9\.\/#-]$
或@emit
的属性更改为您的情况,进而更新了子级。
:value
的工作方式是输入子项的变化,
它会触发一个:currentSate
事件,父级会收到该事件并修改绑定的v-model
,然后回溯到子级。
看起来有些乏味,但最终消除了一系列设计问题。
因此,就您而言,您不应修改@input
。只需:value
新值,然后不修改currentSate
。让父级修改@emit
绑定到currentSate
的内容,这将修改属性data
。
我建议您使用:currentSate
代替currentSate
来遵循Vue约定。如果您发出value
并收到currentSate
,则input
将立即可用。
您可以听“单击”,然后打开属性“ currentSate”的值。只需根据当前值发出下一个值。您仍然需要让父级更新绑定值。
value
以下是监听事件并更新bound属性的示例:
v-model
现在,如果您发出onClick(value){
switch(this.currentSate){
case null: this.$emit('input', true); break;
case true: this.$emit('input', false); break;
case false: this.$emit('input', null); break;
}
}
并绑定到<checkbox v-bind:current-sate="chState" @input='chState=$event'></checkbox>
而不是input
,则可以这样做:
:value
currentSate
适用于以下惯例:将值作为<checkbox v-model="chState"></checkbox>
发出,并将属性作为v-model
接受。
答案 1 :(得分:0)
没有一个答案是完整的 所以就在这里。
Vue.component('checkbox', {
template: '<input type="checkbox" @change="change" class="checkbox-input">',
props: ['value'],
mounted: function () {
this.value = null;
this.$el.indeterminate = true
},
methods: {
change: function () {
if (this.value == null) {
this.$emit('input', true);
return;
}
if (this.value == true) {
this.$emit('input', false);
return;
}
if (this.value == false) {
this.$el.indeterminate = true;
this.$emit('input', null);
return;
}
}
}
});
var myApp = new Vue(
{
el: '#app',
data: {
chState: null,
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<checkbox v-model="chState"></checkbox>
chState = {{chState}}
</div>