2016-11-25 9 views
3

私はVueで再利用可能なスタイル付き入力フィールドを作成しようとしています。スタイルを設定するには(たとえば、アイコンを使用して)別のhtml要素でラップする必要があります。Vueにラップされた<input>を公開する方法?

<styled-input @keyup.enter="doSomething"> 
</styled-input> 

をしかし、これが接続されているため、イベントリスナーに、機能しません。

は、私はそれがそうのように見えるかもしれません StyledInputを使用したい場合は StyledInput

<div class="hasIcon"> 
    <input /> 
    <i class="someIcon"></i> 
<div> 

以下の例を呼び出すことができます<input>の代わりに<div>それに

この問題を回避するには、入力フィールドからすべてのキー・イベントを発行することができます

<div class="hasIcon"> 
    <input @keyup="$emit('keyup', $event) /> 
    <i class="someIcon"></i> 
<div> 

しかし、それは開発者がマップされていない小道具を使用したりするたびに書き換えなければならないので、これはうまくスケールしませんイベント。

内側の要素を誰にでも公開する方法はありますか?

答えて

3

これを達成するには、Vueの方法があるとは思えません。なぜなら、vueイベントを動的にバインドする方法はないからです。しかし、バニラのjavascriptを使用して、その後

Vue.component('my-input', { 
    template: "#my-input", 
    props: ['events'], 
    mounted() { 
    // get the input element 
    let input = document.getElementById('styled-input'); 

    // map events 
    this.events.forEach((event) => { 
     let key = Object.keys(event); 
     input.addEventListener(key, event[key]); 
    }); 
    } 
}) 

あなただけの小道具ので、などのすべてのイベントを通過することができます:

<my-input :events="events"></my-input> 

ビューモデル:

小道具などのイベントは、カスタムイベントを追加する addEventListener()を使用してそれらをマッピング210
var app = new Vue({ 
    el: "#app", 
    data: { 
    events: [{ 
     focus:() => { 
     console.log('focus') 
     } 
    }, { 
     keyup: (e) => { 
     console.log(e.which) 
     } 
    }] 
    } 
}) 

相続人JSFiddle:もちろんhttps://jsfiddle.net/h1dnk40v/

が、これはすべての開発者は、マップのキーコードのようなものなどを行う必要がありますので、あなたは、Vueのが提供する利便性の一部を失うことを意味します。

私が言及することの1つは、Vue componentsは必ずしも無限に再利用可能であるとは限らず、特定の機能を提供し、複雑なロジックをカプセル化することになっているということです。コンポーネントが適合しない場合、その特定のイベントのためにコンポーネントを拡張したり、新しいコンポーネントを作成したりすることができます。

+0

デベロッパーが一貫したコンポーネントAPIを作成するように強制しても、コンポーネントがドキュメント化/マップされたものだけを公開するようにするのは意味があると思います。あなたはどちらも解決策を提示し、良い答えを書いています。ありがとう! –

0

これを実現するにはslotsを使用できます。あなたの<styled-input>テンプレートは次のようになります場合:

<styled-input> 
    <input @keyup.enter="doTheThing"> 
</styled-input> 

それとも、あなたはこのように、入力イベントを気にしない場合は::

<div class="hasIcon"> 
    <slot><input></slot> 
    <i class="someIcon"></i> 
<div> 

次に、あなたがこのようにそれを使用することができます

<styled-input></styled-input> 

とデフォルトのスロットコンテンツ(裸の<input>)が使用されます。CSSを使用してコンポーネント内に<input>のスタイルを設定することはできますが、独自のプロパティやクラスを追加することはできません。したがって、このアプローチは要件に合っているかもしれません。

関連する問題