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.jsでコンポーネント入門!ハンズオン勉強会
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
naokie
July 05, 2016
Technology
320
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Vue.jsでコンポーネント入門!ハンズオン勉強会
https://itstaffing.connpass.com/event/34159/
Vue.jsでコンポーネント入門!ハンズオン勉強会
naokie
July 05, 2016
More Decks by naokie
See All by naokie
あと3年フロントエンドでやる力
naokie
1
1.2k
Other Decks in Technology
See All in Technology
40代で“やっとエンジニアになれた”――閉じた学びを開き、空の青さを知る / 20260628 Naoki Takahashi
shift_evolve
PRO
4
780
レガシーな広告配信システムでのAI駆動開発/運用の挑戦
i16fujimoto
0
120
SONiC実機とGNS3 SONiC VSによる事前コンフィグ検証 ― 生成AIエージェントを環境構築・検証支援に使ってみた ―
sonic
0
120
5分でわかるDuckDB Quack
chanyou0311
2
250
AI Agentをシステムに組み込む前にゆるく向き合ってみる
hayama17
0
110
AWS Security Agent といっしょに脅威モデリングをやってみよう
amarelo_n24
1
200
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
190
クレデンシャル流出 ― 攻撃 3 時間 vs 復旧 10 時間。この非対称性にどう備えるか
kazzpapa3
3
540
千葉での単身赴任からAWSをやり続け、千葉に戻ってきた話
yama3133
1
110
起点・思考・出力で分解する 〜PM業務の自動化設計〜
kazu_kichi_67
1
1k
iOS アプリの「これって不具合ですか?」を AI に調べてもらう
miichan
0
140
感情と身体を置き去りにしない、エンジニアの生きのこり方 ──いまから、ここから「自分の状態」を扱うという選択
saorimurooka
0
320
Featured
See All Featured
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
480
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
170
The Pragmatic Product Professional
lauravandoore
37
7.3k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Rails Girls Zürich Keynote
gr2m
96
14k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
860
The SEO identity crisis: Don't let AI make you average
varn
0
500
From π to Pie charts
rasagy
0
220
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
300
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
440
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
240
Transcript
Vue.jsͰίϯϙʔωϯτೖʂϋϯ ζΦϯษڧձ 2016/07/05(Tue) @DeNA
Web Components ͱʁ
Web ͷ࠶ར༻Մೳͳύʔπ࡞ͷ༷
࠶ར༻ՄೳͳύʔπΛߟ͑Δ্ͰͷΈ • HTML, CSS, JavaScript 3ͭͷઐ༻ݴޠͰߏɻ • HTML ͷෳࡶͳೖΕࢠߏ •
CSS ͷҙਤ͠ͳ͍ద༻ൣғ • JavaScript ͷDOMߏͷґଘ
ߏ͢ΔϦιʔε 1. Custom Elements Ϣʔβʔ͕ಠࣗͷΧελϜཁૉΛఆٛ 2. HTML Imports அยԽͨ͠HTMLϑΝΠϧΛϩʔυ 3.
HTML Template ϒϥβωΠςΟϒͳςϯϓϨʔτػೳ 4. Shadow DOM HTMLʹείʔϓΛܗ
ར༻ͷϝϦοτ • ϚʔΫΞοϓ͕εοΩϦ • ελΠϧͷద༻ൣғΛߜΓࠐΉ • ෳࡶͳߏΛ֎෦͔Βݟ͑ͳ͘͢Δ
ϒϥβͷରԠঢ়گ1
ϒϥβͷରԠঢ়گ2 • Google ओಋͰϒϥβϕϯμͷฒΈόϥόϥ • Polyfill Ͱ࣮࣮͕ͱͯগͳ͍ • Polymer, X-Tag
ͳͲͷϥΠϒϥϦͰ… • ։ൃ͔Β4ͰͦΖͦΖʁ • Vue.js ͳΒ…
Vue.js ͱ Web Components
Vue.js ͷ2ͭͷॏཁͳίϯηϓτ • ϦΞΫςΟϒσʔλόΠϯσΟϯά • ίϯϙʔωϯτγεςϜ
Vue.js ͷίϯϙʔωϯτγεςϜ Custom Elements ͷ༷ʹԊͬͨߏจΛ࣮
ྫ͑… • slot ཁૉ h(ps:/ /www.w3.org/TR/shadow-dom/#slots • is ଐੑ h(ps:/
/www.w3.org/TR/custom-elements/#a(r-is
େنΞϓϦέʔγϣϯྫ1
େنΞϓϦέʔγϣϯྫ2 <div id="app"> <app-nav></app-nav> <app-view> <app-sidebar></app-sidebar> <app-content></app-content> </app-view> </div>
ίϯϙʔωϯτͷ࡞ΛͬͯΈΑ͏
Codepen Ͱ࡞͍͖ͯ͠·͢ɻ ҎԼͷ Pen Λ Fork ͯ͠͡Ί͍ͯͩ͘͞ɻ hands-on-vuejs-vol2-0 - h0p:/
/codepen.io/naokie/pen/rLwLyd
్தܦաΛؒҧͬͯফͯ͠͠·Θͳ͍Α͏ʹɺ Fork ͢Δͱ͖ʹ Loginɺ·ͨ Save as Anonymous ͠·͢ɻ
Vol.1 Ռ
Vol.1 ςϯϓϨʔτ <div id="my-app"> <!-- ৽نλεΫͷՃ --> <p> NewTask: <input
type="text" v-model="newTask" /> <button v-on:click="addTodo">Add</button> </p> <hr /> <!-- λεΫͷϦετදࣔ --> <ul> <li v-for="todo in todos"> <input type="checkbox" v-model="todo.isCompleted" /> <span v-bind:class="{ 'complete': todo.isCompleted }">{{ todo.task }}</span> <button v-on:click="deleteTodo(todo)">Delete</button> </li> </ul> <!-- ΓλεΫͷΧϯτදࣔ --> <p>Remaining Tasks: {{ remains }}/{{ todos.length }}</p> </div>
Vol.1 Vue Πϯελϯε var vm = new Vue({ el: '#my-app',
// Ϛϯτ͢Δཁૉ data: { // ϓϩΩγ͢Δͯ͢ͷϓϩύςΟ newTask: '', todos: [ { task: 'ڇೕΛങ͏', isCompleted: false }, { task: 'ϓϩςΠϯΛങ͏', isCompleted: true }, { task: 'εϙʔπυϦϯΫΛങ͏', isCompleted: false } ] }, computed: { // ࢉग़ϓϩύςΟ remains: function() { var inCompleteList = this.todos.filter(function(task) { return !task.isCompleted; }); return inCompleteList.length; } }, methods: { // Πϯελϯεϝιου addTodo: function() { if (this.newTask == '') return; this.todos.push( { task: this.newTask, isCompleted: false } ); this.newTask = ''; }, deleteTodo: function(todo) { this.todos.$remove(todo); } } });
࠶ར༻Մೳͳ୯Ґʁ 1. ಉ͡ϖʔδͰ܁Γฦ͠දࣔ͢ΔʢϦετදࣔʣ 2. αΠτͰ܁Γฦ͠ར༻͢ΔʢΟδΣοτදࣔʣ
ࠓճ࡞͢Δίϯϙʔωϯτ • Todo ίϯϙʔωϯτͷ࡞ • App ίϯϙʔωϯτͷ࡞
Todo ίϯϙʔωϯτ λεΫ1ͭΛߏ͍ͯ͠ΔύʔπΛίϯϙʔωϯτԽ
HTML Template ΛΓग़͠ <script type="text/template" id="t_todo"> <li> <input type="checkbox" v-model="todo.isCompleted"
/> <span v-bind:class="{ 'complete': todo.isCompleted }">{{ todo.task }}</span> <button v-on:click="deleteTodo(todo)">Delete</button> </li> </script>
Γग़ͨ͠ՕॴΛΧελϜཁૉͰஔ͖͑ <ul> <todo v-for="todo in todos" :todo="todo"></todo> </ul>
είʔϓ • ίϯϙʔωϯτΠϯελϯε֤ࣗʹείʔϓΛ͍࣋ͬͯΔ • ࢠίϯϙʔωϯτσʔλΛࢀরͰ͖ͳ͍
Props σʔλΛࢠίϯϙʔωϯτʹୡ͢ΔΦϓγϣϯ • 2ͭͷम০ࢠ • .sync: two-way όΠϯσΟϯά • .once:
one--me όΠϯσΟϯά • ݕূཁ݅ΛઃఆՄೳ
ίϯϙʔωϯτͷ࡞ var Todo = Vue.extend({ template: '#t_todo', props: { 'todo':
{ required: true } } });
ίϯϙʔωϯτΛొ var vm = new Vue({ ... components: { Todo:
Todo } });
ಈ࡞ͷ֬ೝ • νΣοΫϚʔΫͷ͚֎͠ • ৽نλεΫͷొ • λεΫͷআ • ΓλεΫͷΧϯτදࣔ
λεΫͷআ <button v-on:click="deleteTodo(todo)">Delete</button>
σʔλૢ࡞ͷͱΠϕϯτ • ࡞ͨ͠ Todo ίϯϙʔωϯτͷϝιουͰͳ͍ • λεΫϦετίϯϙʔωϯτ͕อ͍࣋ͯ͠Δ • λεΫϦετͷૢ࡞ίϯϙʔωϯτͷ •
ࢠίϯϙʔωϯτΠϕϯτͷΈ௨ • ࢠؒͰͷΠϕϯτཧ͕ඞཁʹ
ΧελϜΠϕϯτ ίϯϙʔωϯτؒͷΠϕϯτ௨৴ͷΈ • $on() Λ༻ͯ͠ΠϕϯτΛϦοεϯ͠·͢ • $emit() Λ༻ͯࣗ͠ͷΠϕϯτΛτϦΨʔ͠·͢ • $dispatch()
Λ༻ͯ͠ํʹΠϕϯτΛૹग़͠·͢ • $broadcast() Λ༻ͯ͠ࢠଙํʹΠϕϯτΛग़͠·͢
Todo ίϯϙʔωϯτ͔ΒΠϕϯτΛૹग़ var Todo = Vue.extend({ ... methods: { deleteTodo:
function(todo) { this.$dispatch('delete', todo); } } });
ͰΠϕϯτΛϦοεϯ var vm = new Vue({ ... events: { 'delete':
function(todo) { this.todos.$remove(todo); } } });
͜͜·ͰͷՌ hands-on-vuejs-vol2-1 - h0p:/ /codepen.io/naokie/pen/qNjNAw
App ίϯϙʔωϯτ খ͞ͳΞϓϦʢΟδΣοτʣΛίϯϙʔωϯτԽ
HTML Template ΛΓग़͠ <script type="text/template" id="t_app"> <!-- divཁૉͰғΉ --> <div>
<p> NewTask: <input type="text" v-model="newTask" /> <button v-on:click="addTodo">Add</button> </p> <hr /> <ul> <todo v-for="todo in todos" :todo="todo"></todo> </ul> <p>Remaining Tasks: {{ remains }}/{{ todos.length }}</p> </div> </script>
ϑϥάϝϯτΠϯελϯε • ςϯϓϨʔτͷίϯςϯπɺΧελϜཁૉΛஔ͖͑Δ • ςϯϓϨʔτ୯ҰͷϧʔτཁૉΛ࣋ͭͷ͕ਪ
Γग़ͨ͠ՕॴΛΧελϜཁૉͰஔ͖͑ <app :todos="todos"></app>
ίϯϙʔωϯτͷ࡞ var App = Vue.extend({ template: '#t_app', props: { 'todos':
{ required: true } }, ... components: { Todo: Todo } });
ίϯϙʔωϯτΛొ var vm = new Vue({ ... components: { App:
App } });
ಈ࡞ͷ֬ೝ • νΣοΫϚʔΫͷ͚֎͠ • ৽نλεΫͷొ • λεΫͷআ • ΓλεΫͷΧϯτදࣔ
৽نλεΫͷొ <button v-on:click="addTodo">Add</button>
App ίϯϙʔωϯτ͔ΒΠϕϯτΛૹग़ var App = Vue.extend({ // ίϯϙʔωϯτఆٛͰॳظσʔλΦϒδΣΫτΛฦؔ͢ͱͯ͠એݴ͢Δ data: function()
{ return { newTask: '', }; }, ... methods: { addTodo: function() { if (this.newTask == '') return; this.$dispatch('add', this.newTask); this.newTask = ''; } } });
ͰΠϕϯτΛϦοεϯ var vm = new Vue({ ... events: { ...
'add': function(newTask) { this.todos.push( { task: newTask, isCompleted: false } ); } } });
ΓλεΫͷΧϯτදࣔ var App = Vue.extend({ ... computed: { remains: function()
{ var inCompleteList = this.todos.filter(function(task) { return !task.isCompleted; }); return inCompleteList.length; } }, ... });
࠶ར༻Մೳͳύʔπͷ <div id="my-app"> <app :todos="todos"></app> <app :todos="todos"></app> <app :todos="todos"></app> </div>
͜͜·ͰͷՌ hands-on-vuejs-vol2-2 - h/p:/ /codepen.io/naokie/pen/oLwLAj
One more thing...
App ίϯϙʔωϯτ͝ͱʹݟग़͠ΛՃ
εϩοτ • ίϯϙʔωϯτ༻ऀ͕ίϯςϯπΛՃ͢ΔΈ • είʔϓͰίϯϙʔωϯτʹίϯςϯπΛՃ • ໊લ͖ͭεϩοτͰෳ࣋ͭ͜ͱՄೳ
ςϯϓϨʔτʹ slot ཁૉΛՃ <script type="text/template" id="t_app"> <div> <slot></slot> ... </div>
</script>
App ίϯϙʔωϯτ༻ՕॴͰݟग़͠ΛՃ <div id="my-app"> <app :todos="todos"> <h1>ϝΠϯ</h1> </app> <app :todos="todos">
<h1>αϒ</h1> </app> <app :todos="todos"></app> </div>
͜͜·ͰͷՌ hands-on-vuejs-vol2-3 - h0p:/ /codepen.io/naokie/pen/NAgRWY
ͬͯΈΑ͏ NewTask ίϯϙʔωϯτ
ςϯϓϨʔτ <script type="text/template" id="t_newtask"> <p> NewTask: <input type="text" v-model="newTask" />
<button v-on:click="addTodo">Add</button> </p> </script>
ίϯϙʔωϯτԽ var NewTask = Vue.extend({ template: '#t_newtask', data: function() {
return { newTask: '', }; }, methods: { addTodo: function() { if (this.newTask == '') return; this.$dispatch('add', this.newTask) this.newTask = ''; } } });
ίϯϙʔωϯτͷొ var App = Vue.extend({ ... components: { Todo: Todo,
NewTask: NewTask } });
͜͜·ͰͷՌ hands-on-vuejs-vol2-4 - h0p:/ /codepen.io/naokie/pen/BzkLyJ
ࠓճͷ͓Έ͛ GitHub - h*ps:/ /github.com/naokie/hands-on-vuejs-vol2 Codepen - h*p:/ /codepen.io/collec1on/DoLeNM/