Edited at

Vue.jsでシンプルな入力文字種制限

More than 1 year has passed since last update.

要件そのものにどうも納得がいかなかいが世の中似たような事求められることもありそうだからメモ。


要件


  1. フロントエンドでリアルタイムに入力項目にバリデートをかけたい

  2. 条件外の入力文字列はそもそも入力できないようにしたい

  3. フレームワークはVue.js


検討


  • とりあえずはpatternが使えそう

  • (2)が無ければinputpatternに正規表現を入れてイチイチformタグで囲って入力毎にsubmitしてやれば大体イケそうだが


  • vue-validator使えば多分イケるだろうけどこの程度のことに導入したくない


現時点での結論:


@inputでプロパティとvalueの両方に代入する

<template>

<main id="app"><main id="app">
<h1>Vueでシンプルな入力制限</h1>
<table>
<tbody>
<tr>
<th>数字のみ:</th><td><input type="text" pattern="^[0-9]+" maxlength="20" :value="test1" @input="test1=opt(test1,$event)"></td>
</tr>
</tbody>
</table>
</main>
</template>
<script>
var vue = new Vue({
el:'#app',
data:{
test1:'',
},
methods:{
opt:function(e){
var re = new RegExp(e.target.pattern);
var result = re.exec(e.target.value);
return e.target.value = (result)?result[0]:oldVal;
}
}
})
</script>



  • v-modelv-bind:valuev-on:inputの糖衣構文



  • インライン構文でプロパティに代入するとdispatchEventしなくて良くてスマートな感じ


失敗:カスタムディレクティブ


カスタムディレクティブ

<template>

<main id="app">
<table>
<tbody>
<tr>
<th>数字のみ:</th><td><input type="text" pattern="^[0-9]+" maxlength="10" v-model="test1" v-validate="test1"></td>
</tr>
</tbody>
</table>
</main>
</template>
<script>
var vue = new Vue({
el:'#app',
directives:{
validate:function(el, binding, vnode){
var re = new RegExp(e.target.pattern);
var result = re.exec(binding.value);
el.value = (result)?result[0]:'';
var evt = document.createEvent("HTMLEvents"); // この辺が冗長でアホくさい
evt.initEvent('input', true, true );
el.dispatchEvent(evt);
}
}
});
</script>


  • 値をプロパティに直接入れたいが、binding.value読み取り専用


  • binding.argとかbinding.expressionとかでプロパティ名を取ることは可能だが、v-forの中だったりするとどうしようもなくなる

  • と言ってelのvalueに値を代入してもイベントが起こらないから態々起こさないといけない。


    • これが非常に冗長で美しくない。




DEMO

Vueでシンプルな入力制限 http://jsdo.it/hadakadenkyu/22SK/