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

cam*_*aca 37 onfocus vue.js

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

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

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

<input type="search" v-model="query">
<div class="results-as-you-type" v-if="magic_flag"> ... </div>
Run Code Online (Sandbox Code Playgroud)

然后,

new Vue({
  el: '#search_wrapper',
  data: {
    query: '',
    magic_flag: false
  }
});
Run Code Online (Sandbox Code Playgroud)

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

cam*_*aca 69

显然,这就像在事件处理程序上执行一些代码一样简单.

<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>
Run Code Online (Sandbox Code Playgroud)

  • 您也可以编写方法并调用它们,而不是将太多逻辑放入模板中.但这种方式完全没问题. (4认同)
  • @KelvinZhao它们是本地js事件,这就是为什么它们未在Vue文档中列出的原因。 (2认同)

agm*_*984 7

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

我将展示一个快速示例:

<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'"
>
Run Code Online (Sandbox Code Playgroud)

...

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();
            }
        },
    },
},
Run Code Online (Sandbox Code Playgroud)

在我的示例中,如果当前处于活动状态的字段foo是 4 个字符,那么下一个字段bar将自动聚焦。这种类型的逻辑在处理包含信用卡号、信用卡到期日和信用卡安全代码输入等内容的表单时非常有用。可以通过这种方式改进用户体验。

我希望这能激发你的创造力。观察者很方便,因为它们允许您监听数据模型的变化,并在观察者被触发时根据您的自定义需求采取行动。

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

我展示的观察者有点复杂,因为它是一个“深度”观察者,这意味着它能够观察对象和数组。如果没有deep: true,观察者只会在user被重新分配时被触发,但我们不希望那样。我们正在观看的按键foobaruser

在幕后,deep: true将观察者添加到this.user. 如果没有deep启用,Vue 不会产生响应式维护每个键的成本。

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

watch: {
    user() {
        console.log('this.user changed');
    },
},
Run Code Online (Sandbox Code Playgroud)

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

编辑:为了避免深度观看,已经有一段时间了,但我认为您实际上可以观看这样的键:

watch: {
    'user.foo'() {
        console.log('user foo changed');
    },
},
Run Code Online (Sandbox Code Playgroud)

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

computed: {
    userFoo() {
        return this.user.foo;
    },
},

watch: {
    userFoo() {
        console.log('user foo changed');
    },
},
Run Code Online (Sandbox Code Playgroud)

我添加了这两个额外的例子,以便我们可以很快注意到深度观察会消耗更多资源,因为它更频繁地触发。我个人避免深入观察,而是在合理的情况下进行更精确的观察。

但是,在这个带有user对象的例子中,如果所有的键都对应于输入,那么深度观察是合理的。也就是说它可能是。