LOGv:20171214

それがしたかったVue.js

随時追加

親に与えられた属性値で出力するタグを変更したい

描画関数(render)を使う。
demo

<div id="app">
    <v-heading level="1">Render function!</v-heading>
</div>
new Vue({
    el : '#app',
    components : {
        'v-heading' : {
            props : ['level'],
            render(createElement){
                return createElement( `h${this.$props.level}`, this.$slots.default );
            }
        }
    }
});

コンポーネントにイベントをバインディング

ネイティブのイベントをコンポーネントでバインディングしたい場合はインスタンスプロパティの$listenersを使う。

公式
demo

<div id="app">
    <p style="display:block">ACTION : {{ activeEventName }}</p>
    <custom-input @focus="onFocusEvent" @blur="onBlurEvent"></custom-input>
    <custom-link @click.prevent="onClickEvent">TEXT LINK</custom-link>
</div>
Vue.component('custom-input', {
    template : `<div><input type="text" v-on="$listeners"></div>`
});

Vue.component('custom-link', {
    template : `
        <div><a href="" v-on="$listeners"><slot></slot></a></div>
    `
});

new Vue({
    el : '#app',
    data(){
        return {
            activeEventName : ''
        }
    },
    methods : {
        onClickEvent(e){
            this.$data.activeEventName = 'text link clicked';
        },
        onFocusEvent(e){
            this.$data.activeEventName = 'input elem. was focused';
        },
        onBlurEvent(e){
            this.$data.activeEventName = 'input elem. was blured';
        }
    }
});

できれば、親コンポーネントで

<custom-input @focus.stop="onFocusEvent"></custom-input>

のようにイベント修飾子を使ってネイティブイベントの動作制御を行いたいけど、出来ない感じがする。
※ version2.5.17

一応stackoverflowで質問してみた。
Vue.js : How can I do native events handling of child component from parent component

追記

stackoverflowで回答してくれた。
stop修飾子はevent.preventDefault()ではなくevent.stopImmediatePropagation()なので
ネイティブのイベントを止めたい時は@click.preventとする。


動的コンポーネント

タブのように要素をクリックした時に動的にコンテンツを変更したい場合。

公式
demo

<div id="app">
    <p>select <a href="#" @click.stop="componentSelect">my-component1</a>/<a href="#" @click.stop="componentSelect">my-component2</a></p>
    <hr>
    <keep-alive>
        <component :is="activeComponent"></component>
    </keep-alive>
</div>
Vue.component('my-component1', {
    template : `<div>
        <p>the my-component1 has radio buttons.</p>
        <label><input type="radio" name="type" value="">type 1</label>
        <label><input type="radio" name="type" value="">type 2</label>
    </div>`
});

Vue.component('my-component2', {
    template : `<div>my-component2 has text.</div>`
});

let app = new Vue({
    el : '#app',
    data(){
        return {
            activeComponent : 'my-component1'
        }
    },
    methods : {
        componentSelect(e){
            this.$data.activeComponent = e.currentTarget.childNodes[0].nodeValue;
        }
    }
});

コンポーネントを要素で囲ってやるとコンポーネントのインスタンスがキャッシュされるので
コンポーネント内の状態を維持できる。


コンポーネントでmodelを使う

コンポーネントでmodelを使う

open close