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
seya
May 22, 2018
Programming
16
3.8k
Vue コンポーネント実装パターン
v-meetup vol.7 でのLT資料です。
seya
May 22, 2018
Tweet
Share
More Decks by seya
See All by seya
継続的な評価基準と評価の実行の仕方をアップデートするワークフロー
kazuyaseki
2
100
複数の LLM モデルを扱う上で直面した辛みまとめ
kazuyaseki
3
2k
エンジニアにオススメの Figma 活用
kazuyaseki
16
13k
なぜ私はコードをデザインに使いたいのか
kazuyaseki
9
3.5k
フロントエンド開発のための Figma
kazuyaseki
20
25k
PWAに取り組む前に知っておきたい SPAとSEO
kazuyaseki
10
4.1k
State of SEO for SPA 2018
kazuyaseki
8
5k
Selenium あるある
kazuyaseki
0
1.7k
Other Decks in Programming
See All in Programming
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
550
生成AIでGitHubソースコード取得して仕様書を作成
shukob
0
480
return文におけるstd::moveについて
onihusube
1
1.2k
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
340
Haze - Real time background blurring
chrisbanes
1
510
ChatGPT とつくる PHP で OS 実装
memory1994
PRO
2
110
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
400
testcontainers のススメ
sgash708
1
120
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
210
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
120
Semantic Kernelのネイティブプラグインで知識拡張をしてみる
tomokusaba
0
180
命名をリントする
chiroruxx
1
420
Featured
See All Featured
Gamification - CAS2011
davidbonilla
80
5.1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
450
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
Practical Orchestrator
shlominoach
186
10k
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 = ωΠςΟϒཁૉͬΆ͘ѻ͑Δಠࣗͷίϯϙʔωϯτ͕࡞ΕΔʂ
࠷ޙʹ ࣮υΩϡϝϯτʹ͞Βͬͱॻ͍ͯ͋Δ
Ջ͕͋ͬͨΒυΩϡϝϯτಡ͏ʂ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ