$30 off During Our Annual Pro Sale. View Details »

Vue コンポーネント実装パターン

seya
May 22, 2018

Vue コンポーネント実装パターン

v-meetup vol.7 でのLT資料です。

seya

May 22, 2018
Tweet

More Decks by seya

Other Decks in Programming

Transcript

  1. Vueίϯϙʔωϯτ࣮૷ύλʔϯ
    Controlled Component & Transparent Wrappers

    View Slide

  2. ࣗݾ঺հ
    ໊લ: seya
    ձࣾ: BizReach
    झຯ: GraphQL

    View Slide

  3. Controlled
    Component

    View Slide

  4. v-model ศརͰ͢ΑͶ

    {{ text }}

    View Slide

  5. Ͱ΋ಠࣗͰఆٛͨ͠ίϯϙʔωϯτʹ
    v-model ࢖͍͍ͨ৔߹͸Ͳ͏͢Ε͹͍͍Ͱ͠ΐ͏ʁ



    ←͜Ε࡞Γ͍ͨ

    aria-checked="false"
    >

    ↓͜Μͳײ͡Ͱॻ͍ͯ
    ↓ ͜Μͳײ͡ʹ v-model ࢖͍͍ͨɻΠϕϯτϋϯυϥ౉ͯ͠͝ʹΐ͝ʹΐͱ͔ͨ͘͠ͳ͍ɻ

    View Slide

  6. v-model ͸ :value ͱ @input ͷ
    ૊Έ߹ΘͤͰͰ͖͍ͯΔ

    type="text"
    :value="text"
    @input="$emit('input', $event.target.value)"
    />
    ྫ͑͹
    ͸
    ͱಉ͡

    View Slide

  7. ͳͷͰࢠڙͷํͰ͸͜Μͳײ͡Ͱॻ͍ͯ͋͛ͯ

    @click="toggle"
    :aria-checked="value.toString()"
    >

    <br/>export default {<br/>props: ['value'],<br/>methods: {<br/>toggle() {<br/>this.$emit('input', !this.value);<br/>}<br/>}<br/>};<br/>

    View Slide

  8. ਌ͷํͰ͸ v-model ॻ͍ͯ͋͛Δ͚ͩͰ



    View Slide

  9. ಈ͘ʂ

    View Slide

  10. ͪͳΈʹ value ͱ ˏinput ͷͱ͜ʹͪΌΜͱ໊લ
    ͚͍ͭͨ৔߹͸ model ϓϩύςΟΛ࢖͑͹ՄೳͰ͢
    <br/>export default {<br/>model: {<br/>prop: 'toggled',<br/>event: ‘toggle'<br/>},<br/>props: [‘toggled'],<br/>methods: {<br/>toggle() {<br/>this.$emit('toggle', !this.toggled);<br/>}<br/>}<br/>};<br/>

    View Slide

  11. Transparent
    Wrappers

    View Slide

  12. ͖ͬ͞ͷํ๏Ͱಠࣗͷ input ࡞Δ

    :value="value"
    @input="$emit('input', $event.target.value)"
    />

    View Slide

  13. ͦͯ͠਌Ͱ͸͜ͷཁૉʹϑΥʔΧε͕͔͔ͬͨΒͳʹ͔
    ͠Β࣮ߦ͍ͨ͠ͱ͢Δɻ
    (inputҎ֎ͷͱ͜ΖʹΦʔόʔϨΠ͔͚Δͱ͔)





    View Slide

  14. label΋Ұॹʹ͢Δͱ…ಈ͔ͳ͍ʂʂʂ
    @focus.native ͸ϧʔτͷཁૉΛର৅ʹ͢ΔͨΊ
    Input ͷϑΥʔΧε͸र͑ͳ͍ɻ
    ͔ͱݴͬͯଞͷࢦఆͷํ๏΋ͳ͍ɻ٧Μͩɻ


    {{ label }}
    :value="value"
    @input="$emit('input', $event.target.value)"
    />


    View Slide

  15. JOQVUʹΠϕϯτϦεφʔ
    ͕͍͍ͭͯͳ͍ͳΒ
    JOQVUʹΠϕϯτϦεφʔΛ͚ͭΕ͹
    ͍͍͡Όͳ͍
    Transparent Wrappers

    View Slide

  16. $listeners ͰΠϕϯτϦεφʔΛऔಘͰ͖ΔͷͰɺͦΕΛ಺෦
    ͷ input ʹ౉ͯ͋͛͠Δɻ


    {{ label }}
    :value="value"
    v-on="listeners"
    />


    <br/>computed: {<br/>listeners() {<br/>return {<br/>...this.$listeners,<br/>input: event =><br/>this.$emit('input', event.target.value)<br/>}<br/>}<br/>}<br/>

    View Slide

  17. ͋ͱ͸ @focus.native Λ @focus ʹͯ͋͛͠Ε͹


    :label=“hoge”
    @focus="showOverlay"
    v-model="text"
    />


    View Slide

  18. ಈ͘ʂʂʂ

    View Slide

  19. PlaceholderΛ౉͍ͨ͠৔߹͸ʁ


    placeholder=“text"
    :label="hoge"
    @focus="showOverlay"
    v-model="text"
    />


    View Slide

  20. ࢀߟ: https://jp.vuejs.org/v2/api/#inheritAttrs

    View Slide

  21. inheritAttrs Λ false ʹͯ͠ v-bind ʹ $attrs Λ౉ͤ͹OK


    {{ label }}
    :value="value"
    v-on="listeners"
    v-bind="$attrs"
    />


    <br/>export default {<br/>inheritAttrs: false,<br/>// ଞͷ΍ͭ<br/>}<br/>

    View Slide

  22. ݁࿦
    Controlled Component + Transparent Wrapper
    =
    ωΠςΟϒཁૉͬΆ͘ѻ͑Δಠࣗͷίϯϙʔωϯτ͕࡞ΕΔʂ

    View Slide

  23. ࠷ޙʹ
    ࣮͸υΩϡϝϯτʹ͞Βͬͱॻ͍ͯ͋Δ

    View Slide

  24. Ջ͕͋ͬͨΒυΩϡϝϯτಡ΋͏ʂ

    View Slide

  25. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ

    View Slide