Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Vue コンポーネント実装パターン
seya
May 22, 2018
Programming
16
3.1k
Vue コンポーネント実装パターン
v-meetup vol.7 でのLT資料です。
seya
May 22, 2018
Tweet
Share
More Decks by seya
See All by seya
なぜ私はコードをデザインに使いたいのか
kazuyaseki
8
2.8k
フロントエンド開発のための Figma
kazuyaseki
17
20k
PWAに取り組む前に知っておきたい SPAとSEO
kazuyaseki
9
3.3k
State of SEO for SPA 2018
kazuyaseki
8
3.9k
Selenium あるある
kazuyaseki
0
1.4k
Other Decks in Programming
See All in Programming
あなたの会社の古いシステム、なんとかしませんか?~システム刷新から考えるDX化への道筋とバリエーション~/webinar20220420-systems
grapecity_dev
0
130
機能横断型チームにおける技術改善
takeshiakutsu
3
490
UI State Modeling 어떤게 좋을까?
laco2951
1
240
Kotlin 最新動向2022 #tfcon #techfeed
ntaro
1
1.2k
Unity Localization で多言語対応実装しよう / xrdnk-yokohamaunity-lt10-20220513
xrdnk
0
170
WindowsコンテナDojo:第2回 Windowsコンテナアプリのビルド、公開、デプロイ
oniak3ibm
PRO
0
150
偏見と妄想で語るスクリプト言語としての Swift / Swift as a Scripting Language
lovee
2
280
Enterprise Angular: Frontend Moduliths with Nx and Standalone Components @jax2022
manfredsteyer
PRO
0
310
mrubyを1300円のボードで動かそう
yuuu
0
190
読みやすいコードを書こう
yutorin
0
430
質とスピード(2022春版、質疑応答用資料付き) / Quality and Speed 2022 Spring Edition
twada
PRO
29
19k
Node.js 最新動向 TFCon 2022
yosuke_furukawa
PRO
6
2.9k
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
7
1k
Writing Fast Ruby
sferik
612
57k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
212
20k
Web Components: a chance to create the future
zenorocha
303
40k
Faster Mobile Websites
deanohume
294
28k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
181
15k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
11
4.6k
Designing the Hi-DPI Web
ddemaree
272
32k
Happy Clients
brianwarren
89
5.5k
Gamification - CAS2011
davidbonilla
75
3.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
237
19k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
37
3.2k
Transcript
Vueίϯϙʔωϯτ࣮ύλʔϯ Controlled Component & Transparent Wrappers
ࣗݾհ ໊લ: seya ձࣾ: BizReach झຯ: GraphQL
Controlled Component
v-model ศརͰ͢ΑͶ <input type="text" v-model="text" /> <button>{{ text }}</button>
ͰಠࣗͰఆٛͨ͠ίϯϙʔωϯτʹ v-model ͍͍ͨ߹Ͳ͏͢Ε͍͍Ͱ͠ΐ͏ʁ <form> <toggle-button v-model="toggled" /> </form> ←͜Ε࡞Γ͍ͨ <template>
<span class="toggle" role="checkbox" tabindex=“0" aria-checked="false" ></span> </template> ↓͜Μͳײ͡Ͱॻ͍ͯ ↓ ͜Μͳײ͡ʹ v-model ͍͍ͨɻΠϕϯτϋϯυϥͯ͠͝ʹΐ͝ʹΐͱ͔ͨ͘͠ͳ͍ɻ
v-model :value ͱ @input ͷ Έ߹ΘͤͰͰ͖͍ͯΔ <input type="text" v-model="text"
/> <input type="text" :value="text" @input="$emit('input', $event.target.value)" /> ྫ͑ ͱಉ͡
ͳͷͰࢠڙͷํͰ͜Μͳײ͡Ͱॻ͍ͯ͋͛ͯ <template> <span class="toggle" role="checkbox" tabindex="0" @click="toggle" :aria-checked="value.toString()" ></span> </template>
<script> export default { props: ['value'], methods: { toggle() { this.$emit('input', !this.value); } } }; </script>
ͷํͰ v-model ॻ͍ͯ͋͛Δ͚ͩͰ <form> <toggle-input v-model="someFlag" /> </form>
ಈ͘ʂ
ͪͳΈʹ value ͱ ˏinput ͷͱ͜ʹͪΌΜͱ໊લ ͚͍ͭͨ߹ model ϓϩύςΟΛ͑ՄೳͰ͢ <script> export
default { model: { prop: 'toggled', event: ‘toggle' }, props: [‘toggled'], methods: { toggle() { this.$emit('toggle', !this.toggled); } } }; </script>
Transparent Wrappers
͖ͬ͞ͷํ๏Ͱಠࣗͷ input ࡞Δ <template> <input :value="value" @input="$emit('input', $event.target.value)" /> </template>
ͦͯ͠Ͱ͜ͷཁૉʹϑΥʔΧε͕͔͔ͬͨΒͳʹ͔ ͠Β࣮ߦ͍ͨ͠ͱ͢Δɻ (inputҎ֎ͷͱ͜ΖʹΦʔόʔϨΠ͔͚Δͱ͔) <template> <form> <custom-input @focus.native="showOverlay" /> </form> </template>
labelҰॹʹ͢Δͱ…ಈ͔ͳ͍ʂʂʂ @focus.native ϧʔτͷཁૉΛରʹ͢ΔͨΊ Input ͷϑΥʔΧεर͑ͳ͍ɻ ͔ͱݴͬͯଞͷࢦఆͷํ๏ͳ͍ɻ٧Μͩɻ <template> <label> {{ label
}} <input :value="value" @input="$emit('input', $event.target.value)" /> </label> </template>
JOQVUʹΠϕϯτϦεφʔ ͕͍͍ͭͯͳ͍ͳΒ JOQVUʹΠϕϯτϦεφʔΛ͚ͭΕ ͍͍͡Όͳ͍ Transparent Wrappers
$listeners ͰΠϕϯτϦεφʔΛऔಘͰ͖ΔͷͰɺͦΕΛ෦ ͷ input ʹͯ͋͛͠Δɻ <template> <label> {{ label }}
<input :value="value" v-on="listeners" /> </label> </template> <script> computed: { listeners() { return { ...this.$listeners, input: event => this.$emit('input', event.target.value) } } } </script>
͋ͱ @focus.native Λ @focus ʹͯ͋͛͠Ε <template> <form> <custom-input :label=“hoge” @focus="showOverlay"
v-model="text" /> </form> </template>
ಈ͘ʂʂʂ
PlaceholderΛ͍ͨ͠߹ʁ <template> <form> <custom-input placeholder=“text" :label="hoge" @focus="showOverlay" v-model="text" /> </form>
</template>
ࢀߟ: https://jp.vuejs.org/v2/api/#inheritAttrs
inheritAttrs Λ false ʹͯ͠ v-bind ʹ $attrs ΛͤOK <template> <label>
{{ label }} <input :value="value" v-on="listeners" v-bind="$attrs" /> </label> </template> <script> export default { inheritAttrs: false, // ଞͷͭ } </script>
݁ Controlled Component + Transparent Wrapper = ωΠςΟϒཁૉͬΆ͘ѻ͑Δಠࣗͷίϯϙʔωϯτ͕࡞ΕΔʂ
࠷ޙʹ ࣮υΩϡϝϯτʹ͞Βͬͱॻ͍ͯ͋Δ
Ջ͕͋ͬͨΒυΩϡϝϯτಡ͏ʂ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ