代码之家  ›  专栏  ›  技术社区  ›  cambraca

Vue。JS值绑定到具有焦点的输入

  •  63
  • cambraca  · 技术社区  · 7 年前

    当输入获得/失去焦点时,是否有方法更改模型中的值?

    这里的用例是一个搜索输入,它在您键入时显示结果,只有当焦点在搜索框上时才会显示这些结果。

    以下是我目前的情况:

    <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 回复  |  直到 6 年前
        1
  •  119
  •   tony19 Ashutosh Narang    2 年前

    显然,这就像在 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>
    
        2
  •  7
  •   agm1984    4 年前

    在更复杂的场景中处理类似情况的另一种方法可能是允许表单跟踪当前活动的字段,然后使用观察者。

    我将展示一个快速示例:

    <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 将自动聚焦。当处理具有信用卡号、信用卡到期日和信用卡安全代码输入等内容的表单时,这种类型的逻辑非常有用。可以通过这种方式改进用户体验。

    我希望这能激发你的创造力。监视程序非常方便,因为它们允许您监听数据模型的更改,并在触发监视程序时根据您的自定义需求进行操作。

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

    我展示的观察器有点复杂,因为它是一个“深度”观察器,这意味着它能够观察对象和数组。没有 deep: true ,只有在以下情况下才会触发观察者 user 被重新分配,但我们不想这样。我们在看钥匙 酒吧 在…上 使用者 .

    在幕后, 深:真的 正在向所有关键点添加观察者 this.user 没有 deep 启用后,Vue合理地不会产生以反应方式维护每个密钥的成本。

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

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

    注意:如果你发现我有 handler(user) { 或者,你本来可以 handler(oldValue, newValue) { 但是您注意到,两者显示相同的值,这是因为两者都是对相同的引用 使用者 对象点击此处了解更多信息: https://github.com/vuejs/vue/issues/2164

    编辑:为了避免深入观察,已经有一段时间了,但我认为你实际上可以像这样观察一个关键点:

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

    但如果这不起作用,你也可以制作一个计算的道具,然后观看:

    computed: {
        userFoo() {
            return this.user.foo;
        },
    },
    
    watch: {
        userFoo() {
            console.log('user foo changed');
        },
    },
    

    我添加了这两个额外的示例,以便我们可以快速注意到深度监视将消耗更多的资源,因为它触发的频率更高。我个人避免深入观察,只要合理,就更精确地观察。

    然而,在本例中 使用者 对象,如果所有键都对应于输入,则深入观察是合理的。也就是说,它可能是。

        3
  •  3
  •   fitorec    5 年前

    你可以通过确定一个特殊的 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>

    祝你好运

        4
  •  1
  •   Rodney P. Barbati    7 年前

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

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

    查看@event.capture。