Vue.JS值与具有焦点的输入相关联

时间:2017-01-11 21:48:00

标签: vue.js onfocus

当输入获得/失去焦点时,有没有办法在模型中更改值?

此处的用例是一个搜索输入,可在您键入时显示结果,这些只应在焦点位于搜索框时显示。

这是我到目前为止所拥有的:

<input type="search" v-model="query">
<div class="results-as-you-type" v-if="magic_flag"> ... </div>

然后,

new Vue({
  el: '#search_wrapper',
  data: {
    query: '',
    magic_flag: false
  }
});

这里的想法是,当搜索框具有焦点时,magic_flag应转向true。我可以手动执行此操作(例如,使用jQuery),但我想要一个纯粹的Vue.JS解决方案。

4 个答案:

答案 0 :(得分:56)

显然,这就像在event handlers上做一些代码一样简单。

<input 
  type="search" 
  v-model="query"
  @focus="magic_flag = true"
  @blur="magic_flag = false"
/>
<div class="results-as-you-type" v-if="magic_flag"> ... </div>

答案 1 :(得分:0)

当用户将鼠标悬停在输入上时,您可能还想激活搜索 - @moverover = ...

此类功能的另一种方法是,即使鼠标位于结果列表中,过滤器输入也始终处于活动状态。键入任何字母都会修改滤镜输入而不会更改焦点。许多实现实际上只在输入字母或数字后显示过滤器输入框。

查看@ event.capture。

答案 2 :(得分:0)

在更复杂的情况下处理此类问题的另一种方法可能是允许表单跟踪当前哪个字段处于活动状态,然后使用观察程序。

我将显示一个快速示例:

<input
    v-model="user.foo"
    type="text"
    name="foo"
    @focus="currentlyActiveField = 'foo'"
>

<input
    ref="bar"
    v-model="user.bar"
    type="text"
    name="bar"
    @focus="currentlyActiveField = 'bar'"
>

...

data() {
    return {
        currentlyActiveField: '',
        user: {
            foo: '',
            bar: '',
        },
    };
},

watch: {
    user: {
        deep: true,
        handler(user) {
            if ((this.currentlyActiveField === 'foo') && (user.foo.length === 4)) {
                // the field is focused and some condition is met
                this.$refs.bar.focus();
            }
        },
    },
},

在这里的示例中,如果当前活动字段为foo,并且值的长度为4个字符,则下一个字段bar将自动聚焦。在处理包含信用卡号,信用卡到期和信用卡安全码输入之类的表格时,这种逻辑很有用。 UX可以通过这种方式进行改进。

我希望这可以激发您的创造力。观察者很方便,因为它们使您可以监听数据模型的更改,并在触发观察者时根据您的自定义需求采取行动。

在我的示例中,您可以看到每个输入都已命名,并且组件知道当前正在关注哪个输入,因为它正在跟踪currentlyActiveField

我显示的观察器稍微复杂一点,因为它是“深度”观察器,这意味着它能够监视对象和数组。如果没有deep: true,则仅在重新分配user时才会触发观察者,但是我们不希望这样。我们正在观看foo上的键baruser

deep: true在幕后将观察者添加到this.user上的所有键上。否则,Vue不会因此而产生成本。

一个简单的观察者会是这样的:

watch: {
    user() {
        console.log('user changed');
    },
},

注意:如果您发现我有handler(user) {的地方,您可能有handler(oldValue, newValue) {,但是您注意到两者显示的值相同,这是因为两者都是对相同的user的引用宾语。在此处阅读更多信息:https://github.com/vuejs/vue/issues/2164

答案 3 :(得分:0)

您可以通过确定特殊的 CSS class使用单位,例如,这是一个简单的代码段:

var vm = new Vue({
	el: '#app',
	data: {
		content: 'click to change content',
		flat_input_active: false
	},
	methods: {
		onFocus: function(event) {
	    	    event.target.select();
	    	    this.flat_input_active = true;
		},
		onBlur: function(event) {
	    	    this.flat_input_active = false;
		}
	},
	computed: {
		clazz: function() {
			var clzz = 'control-form';
			if (this.flat_input_active == false) {
				clzz += ' only-text';
			}
			return clzz;
		}
	}
});
#app {
  background: #EEE;
}
input.only-text { /* special css class */
  border: none;
  background: none;
}
<!-- libraries -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<!-- html template -->
<div id='app'>
	<h1>
	<input v-model='content' :class='clazz'
		@focus="onFocus($event)"
		@blur="onBlur"/>
	</h1>
<div>

祝你好运