入力がフォーカスを取得/失うときにモデルの値を変更する方法はありますか?
ここでの使用例は、入力時に結果を表示する検索入力です。これらは、検索ボックスにフォーカスがある場合にのみ表示されます。
ここに私が持っているものがあります:
<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ソリューションが必要です。
どうやら、これは 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>
このようなことをより複雑なシナリオで処理する別の方法は、フォームが現在アクティブなフィールドを追跡し、ウォッチャーを使用することです。
簡単なサンプルを示します。
<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
のキーbar
およびuser
を監視しています。
舞台裏では、deep: true
はthis.user
のすべてのキーにオブザーバーを追加しています。それ以外の場合、Vueはこれを行うコストを負いません。
単純なウォッチャーは次のようになります。
watch: {
user() {
console.log('user changed');
},
},
注:handler(user) {
がある場所を発見した場合、handler(oldValue, newValue) {
を持つことができますが、両方とも同じ値を表示することに気付きます。これは、両方が同じuser
オブジェクトへの参照だからです。詳細はこちら: https://github.com/vuejs/vue/issues/2164
特別なCSSclass
を決定することにより、フラットを使用できます。たとえば、次の単純なスニペットです。
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>
幸運
ユーザーが入力の上にマウスを置いたときに検索をアクティブにすることもできます-@mouseover = ...
この種の機能に対する別のアプローチは、マウスが結果リストにある場合でも、フィルター入力が常にアクティブであることです。文字を入力すると、フォーカスを変更せずにフィルター入力が変更されます。多くの実装では、実際に文字または数字を入力した後にのみフィルター入力ボックスが表示されます。
@ event.captureを調べてください。