Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Vue コンポーネント実装パターン
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
seya
May 22, 2018
Programming
16
4k
Vue コンポーネント実装パターン
v-meetup vol.7 でのLT資料です。
seya
May 22, 2018
Tweet
Share
More Decks by seya
See All by seya
継続的な評価基準と評価の実行の仕方をアップデートするワークフロー
kazuyaseki
2
360
複数の LLM モデルを扱う上で直面した辛みまとめ
kazuyaseki
3
2.4k
エンジニアにオススメの Figma 活用
kazuyaseki
16
15k
なぜ私はコードをデザインに使いたいのか
kazuyaseki
9
3.7k
フロントエンド開発のための Figma
kazuyaseki
20
26k
PWAに取り組む前に知っておきたい SPAとSEO
kazuyaseki
10
4.5k
State of SEO for SPA 2018
kazuyaseki
8
5.3k
Selenium あるある
kazuyaseki
0
1.8k
Other Decks in Programming
See All in Programming
プロダクトオーナーから見たSOC2 _SOC2ゆるミートアップ#2
kekekenta
0
230
AIによる高速開発をどう制御するか? ガードレール設置で開発速度と品質を両立させたチームの事例
tonkotsuboy_com
7
2.4k
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
140
生成AIを活用したソフトウェア開発ライフサイクル変革の現在値
hiroyukimori
PRO
0
110
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
470
AI時代の認知負荷との向き合い方
optfit
0
170
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
1
250
Package Management Learnings from Homebrew
mikemcquaid
0
230
CSC307 Lecture 06
javiergs
PRO
0
690
Fluid Templating in TYPO3 14
s2b
0
130
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
4.4k
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
180
Featured
See All Featured
Code Review Best Practice
trishagee
74
20k
Why Our Code Smells
bkeepers
PRO
340
58k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.8k
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
1.9k
The Cult of Friendly URLs
andyhume
79
6.8k
Designing for Timeless Needs
cassininazir
0
130
Measuring & Analyzing Core Web Vitals
bluesmoon
9
760
The Limits of Empathy - UXLibs8
cassininazir
1
220
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.6k
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 = ωΠςΟϒཁૉͬΆ͘ѻ͑Δಠࣗͷίϯϙʔωϯτ͕࡞ΕΔʂ
࠷ޙʹ ࣮υΩϡϝϯτʹ͞Βͬͱॻ͍ͯ͋Δ
Ջ͕͋ͬͨΒυΩϡϝϯτಡ͏ʂ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ