2017-12-12 21 views
0

多分簡単な質問ですが、基本的なラッパーコンポーネントを作成する正しい方法を見つけることができません。たとえば、私はこのような選択があります。VueJS 2.4基本ラッパーコンポーネント

<select v-model="foo" name="bar" v-validate="'required'" v-bind:class="{ invalid: errors.has('bar') }"> 
    <option value="">Default</option> 
    <option value="1">Value 1</option> 
    <option value="2">Value 2</option> 
</select> 

を私はクラスcustom-selectでこのarroundのいくつかの砂糖、divを追加する必要があります。だから私は、ネイティブをラップするcustom-selectコンポーネントを作成している選択:

Vue.component('custom-select', { 
    template: ` 
     <div class="custom-select"> 
      <select v-on="$listeners" v-bind="$props"> 
       <slot></slot> 
      </select> 
     </div> 
    `, 
}); 

私の問題は私のコンポーネントがv-modelclassなどの小道具を継承していないということです。私はグローバルな方法があるかどうか、コンポーネントのすべての小道具を書き換えずにすべてを継承させることができるかどうかを知りたいですか?

おかげ

+0

をあなたのカスタムコンポーネントがスロットとして選択を取るようにしたいかもしれません。いずれにしても、「vモデル」は支柱ではなく、それを階層の下で直接プロキシする方法はありません。 –

答えて

1

v-model:value@inputのためだけの構文糖です。これは、ネイティブの入力要素ではコンポーネントとは異なる方法で動作します。コンポーネントのテンプレートにv-on="$listeners" v-bind="$props"を追加するだけでは簡単ではありません。それは動作しません。あなたが仕事にv-modelをしたい場合は

は、コンポーネント内の入力イベントを処理し、変更した値放出する必要があります

<custom-select v-model="selected"> 
Vue.component('custom-select', { 
    template: ` 
    <div class="custom-select"> 
     <select v-bind="$attrs" v-on="computedListeners"> 
     <slot></slot> 
     </select> 
    </div> 
    `, 
    computed: { 
    computedListeners() { 
     return Object.assign({}, this.$listeners, { 
     input: e => this.$emit('input', e.target.value), 
     }); 
    }, 
    }, 
}); 

を上記v-model作品を作るためのハックの一種であります

<custom-select :value="selected" @input="selected = $event.target.value"> 
Vue.component('custom-select', { 
    template: ` 
    <div class="custom-select"> 
     <select v-bind="$attrs" v-on="$listeners"> 
     <slot></slot> 
     </select> 
    </div> 
    `, 
}); 

注THA:正しく、そうでなければ、単にこれを行うことができますt classstyleは、内部では<select>にプロキシすることはできません。プロンプトではないため、Vueによって特別に処理され、コンポーネントのテンプレートのルート要素に適用されるためです。

EDIT:実際にプロキシclassstyleをすることができますが、それは手動で描画する関数を書く必要があります。

Vue.component('custom-select', { 
    functional: true, 
    render(h, ctx) { 
    const on = Object.assign({}, ctx.listeners); 
    if (ctx.listeners.input) { 
     // Required for v-model to work 
     on.input = e => ctx.listeners.input(e.target.value); 
    } 

    const data = Object.assign({}, ctx.data, { on }); 
    return h('div', { class: 'custom-select' }, [h('select', data, ctx.children)]); 
    }, 
}); 
+0

あなたの例では 'v-bind:disabled = ...'をどのように扱いますか?コンポーネントには無効化された小道具が必要ですか?私の質問のポイントは、この種のバインディングをすべて記述する必要はありません。 – Mushr00m

+0

私の更新された答えを見てください。 –

+0

詳細な回答ありがとうございます – Mushr00m