我将材质设计输入字段设为Vue组件。我监听焦点事件并运行一个函数来检查每次用户聚焦时的值。这是代码:
<template>
<span class="h-input-container">
<input :type="type" :name="name" v-validate="validation"
@focusout="classHandle" :id="id" :value="value">
<p :class="focusClass"><i :class="icon"></i> {{placeholder}}</p>
</span>
</template>
<script>
export default {
mounted: function(){
if (this.value != '') {
this.focusClass = 'focused'
}
},
props: {
placeholder: {
default: ''
},
name: {
default: 'no-name'
},
type: {
default: 'text'
},
validation: {
default: ''
},
icon: {
default: ''
},
id: {
default: ''
},
value: {
default: ''
}
},
data: function(){
return {
focusClass: '',
}
},
methods: {
classHandle: function(event){
if (event.target.value != '') {
this.focusClass = 'focused'
} else {
this.focusClass = ''
}
}
}
};
</script>
我将值作为名为value
的道具传递,我使用:value="value"
将该值用于输入字段。问题是,每次方法classHandle
运行时,输入字段的值都会消失。我无法弄清楚原因。
答案 0 :(得分:2)
为了澄清接受的答案,Vue没有&#34;刷新&#34; focusout
处理程序触发时的值。属性value
从未更改过,输入元素的值已更改。
更改focusClass
强制Vue将组件重新呈现给DOM。因为您已告诉Vue使用该属性value
作为通过:value="value"
输入的值,它使用属性的当前状态,从未更改如上所述,渲染组件和输入中输入的内容都会消失。
接受的答案继续说明你应该通过更新this.value
来解决这个问题。在组件中,Vue将允许您这样做,但它会在控制台中发出警告。
[Vue警告]:避免直接改变道具,因为该值将是 父组件重新渲染时会覆盖。相反,使用 基于prop值的数据或计算属性。支持存在 变异:&#34;价值&#34;
Vue中组件的属性就像javascript中的函数参数一样。在组件内部,可以更改它们,但该更改仅限于组件的范围。如果父组件必须重新渲染,那么属性&#34; value&#34;您的输入将使用父版本的值重新绘制,您将失去更改。
在Vue&#34; Component communication支持事件,#34;要更改组件外部的值,您必须$emit
它。以下是适用的组件版本,不会发出任何警告,并且可以正确地发出更改。
{
props: {
placeholder: {
default: ''
},
name: {
default: 'no-name'
},
type: {
default: 'text'
},
validation: {
default: ''
},
icon: {
default: ''
},
id: {
default: ''
},
value: {
default: ''
}
},
template:`
<div class="h-input-container" style="background-color: lightgray">
<input :type="type" :name="name"
@focusout="classHandle" :id="id" :value="value" @input="$emit('input', $event.target.value)" />
<p :class="focusClass"><i :class="icon"></i> {{placeholder}}</p>
</div>
`,
data: function() {
return {
focusClass: '',
}
},
methods: {
classHandle: function(event) {
if (event.target.value != '') {
this.focusClass = 'focused'
} else {
this.focusClass = ''
}
}
}
}
我已经整理了example来证明这两种方法的不同之处。
通常情况下,我不会使用:value="value" @input="$emit('input', $event.target.value)"
而是使用v-model
,但您也使用:type="type"
,而Vue会发出警告,要求v-model
使用awk
动态类型。
答案 1 :(得分:0)
当您在输入中进行更改时,您当前的组件似乎不会刷新this.value
。当您使用focusOut时,Vue会导致组件刷新,并且由于您的值未更新,因此显示为empy。要解决您的问题,您需要更新活动this.value
input
new Vue(
{
el: '#app',
props: {
placeholder: {
default: ''
},
name: {
default: 'no-name'
},
type: {
default: 'text'
},
validation: {
default: ''
},
icon: {
default: ''
},
id: {
default: ''
},
value: {
default: ''
}
},
data: function() {
return {
focusClass: '',
}
},
methods: {
updateValue(event) {
this.value = event.target.value
},
classHandle: function(event) {
if (event.target.value != '') {
this.focusClass = 'focused'
} else {
this.focusClass = ''
}
}
}
});
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="app">
<span class="h-input-container">
<input :type="type" :name="name" v-validate="validation"
@focusout="classHandle" :id="id" :value="value" @input="updateValue" />
<p :class="focusClass"><i :class="icon"></i> {{placeholder}}</p>
</span>
</div>
所以你应该注意:
@input="updateValue"
和
updateValue(event) {
this.value = event.target.value
}