基于官方示例Custom Input Component example:
HTML:
<div id="app" >
<div :class="{'has-value' : hasValue}">
<input type="text"
ref="input"
v-bind:value="value"
@input="onInput" >
</div>
</div>
JS:
new Vue({
el: '#app',
data: function() {
return {
hasValue: false
}
},
props: ['value'],
methods:{
onInput: function(){
val= this.$refs.input.value
if(val && val.length > 0){
this.hasValue = true
} else {
this.hasValue = false
}
}
}
})
预期:
动态设置hasValue
数据以进行输入,并将Css类绑定到此数据
意外的: 只有在初始化并键入第一个字符后,才会从输入中删除键入的字符。按JS-Fiddle-&gt;运行再次查看。
在第一个角色之后,一切都按预期工作。
如果我删除v-bind:value="value"
或评论\\this.hasValue = true
,则按预期方式工作。对于自定义输入组件,建议使用绑定值prop。
这是为了什么?为什么?或者这是我应该报告的错误?
答案 0 :(得分:6)
这是预期的行为:
hasValue
从false
更改为true
,导致组件重新呈现value
道具)是空的。hasValue
不再发生变化,因此无法重新渲染,因此,Vue不再重置输入字段的值。首先,您必须了解Vue是数据驱动的 - 数据决定HTML,而不是相反。因此,如果您希望输入具有值,则必须在绑定到它的属性中反映该值。
如果使用本地数据属性,这将是微不足道的:
https://jsfiddle.net/Linusborg/jwok2jsx/2/
但是既然你使用了道具,并且我假设你想继续使用道具,那么这种情况就会有所不同 - Vue遵循“数据向下 - 事件向上”的模式。你不能在孩子内部改变道具,你必须告诉你从中得到它的父,你想用事件来改变它。改变它的责任将是父母的责任。以下是具有正确父子关系的示例:
答案 1 :(得分:0)
我猜测当你修改hasValue
时,Vue会重新渲染组件(将has-value
类应用于div),这会导致v-bind:value
被重新设置-evaluated。 value
是一个未分配且永不改变的prop,因此输入元素的值被清除。
您确实应该在输入元素上使用v-model
并根据模型中的has-value
控制value
,而不是直接与DOM进行交互。 (虽然v-model
是道具并且无法从组件中分配,但您仍然无法将value
与value
一起使用。)
我还猜测你想制作一个自定义输入组件,当它有一个值时应用某种风格。试试这个:
Vue.component('my-input', {
props: ['value'],
template: `<input class="my-input" :class="{ 'has-value': value }" type="text" :value="value" @input="$emit('input', $event.target.value)">`,
});
new Vue({
el: '#app',
data: {
value: '',
},
});
&#13;
.my-input.has-value {
background-color: yellow;
}
&#13;
<script src="https://unpkg.com/vue@2.5.6/dist/vue.js"></script>
<div id="app">
<my-input v-model="value"></my-input>
</div>
&#13;
答案 2 :(得分:0)
你想要达到这样的目标吗?
new Vue({
el: '#app',
data: {
input: ''
},
computed: {
hasValue () {
return this.input.length ? true : false
}
}
})
.has-value {
background-color: red;
}
<div id="app">
<div :class="{'has-value' : hasValue}">
<input type="text" v-model="input">
</div>
</div>
<script src="https://unpkg.com/vue"></script>