Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Rails使いのNuxt.js入門 - 銀座Rails#12
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
nof
August 29, 2019
Programming
2.3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rails使いのNuxt.js入門 - 銀座Rails#12
nof
August 29, 2019
More Decks by nof
See All by nof
オープンセミナー2020@広島 発表資料
nof
1
1.1k
Stripeでよかった
nof
0
150
Other Decks in Programming
See All in Programming
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
470
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
840
The Rails Doctrine Decade
koic
2
460
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
220
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
AHC070解法紹介
eijirou
0
150
mrbgem 三角測量 開発
ogom
0
180
Verilogで学ぶCPU自作入門.pdf
uyuki234
7
3.9k
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.3k
速習iPhone Duo対応
yuukiw00w
2
940
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
470
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
250
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
510
Facilitating Awesome Meetings
lara
57
7.2k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
The Curse of the Amulet
leimatthew05
3
15k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
380
The Language of Interfaces
destraynor
162
27k
WENDY [Excerpt]
tessaabrams
14
40k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
270
Transcript
Rails͍ͷNuxt.jsೖ ۜ࠲Rails#12 2019/08/29 גࣜձࣾιχοΫΨʔσϯ ࡔխढ़
ࣗݾհ • ࡔխढ़ @ssh_nof • גࣜձࣾιχοΫΨʔσϯॴଐ • ౡͷ͔ࣗΒϦϞʔτϫʔΫ • झຯɿαφ
(༵αφͷ)
͢͜ͱ • Rails ϓϩάϥϚͷ͕ Nuxt.js Ͱ։ൃ͢Δ࣌ͷྲྀΕ • ࡐΑ͋͘ΔTODOফ͠ࠐΈॲཧ • ͍ͬͪΐ৮ͬͯΈΑ͏͔ͳͱࢥͬͯΒ͏ͨΊͷೖฤ
Nuxt.js ?
Nuxt.js • Vue.js ։ൃͷͨΊͷϑϨʔϜϫʔΫ • SSR (αʔόʔαΠυϨϯμϦϯά) • SPA (γϯάϧϖʔδΞϓϦέʔγϣϯ)
• ଞʹϑϨʔϜϫʔΫͱͯ͠ͷ༷ʑͳػೳ͕͋Γ·͕͢ɺׂѪ ࠓճͪ͜Β
͓
Πϝʔδ νΣοΫϘοΫεͷΫϦοΫͰɺϦετΛΓସ͑ ↓ νΣοΫϘοΫεͷΫϦοΫ ͬͨ͜ͱϦετʹҠಈ
ϓϩδΣΫτͷ࡞ʙىಈ
ϓϩδΣΫτΛ࡞Δ w CPPUTUSBQ w WVFUJGZ w CVMNB w UFJMXJOE w
FMFNFOUVJ w CVFGZ w &4-JOU͏ w 1SFUUJFS͏ w OQNPSZBSO ରࣜͰઃఆ npx create-nux-app <project name> ( npx :μϯϩʔυ͔Β࣮ߦ·ͰҰൃͰͰ͖ΔίϚϯυɻ࠷ۙͷ Node.js ʹೖ͍ͬͯ·͢ɻ )
ىಈ http://localhost:3000/ $ cd todo-list $ yarn dev ϑΝΠϧͷฤूͰࣗಈͰը໘͕ΓସΘΓ·͢ (ϗοτϦϩʔυ)
+
։ൃ͢Δ
pugʹ͍ͭͯগ͠ <template lang="pug"> ul.list-group li.list-group-item foo li.list-group-item bar </template> •
؆ུه๏ͰHTMLΛָʹॻ͚ΔςϯϓϨʔτΤϯδϯ • Rails͍ͷօ༷ʹ͓ͳ͡Έͷ slim ͱ΄ͱΜͲಉ͡ • yarn add —dev pug pug-plain-loader ͰΠϯετʔϧ • ࠓճHTMLͰઆ໌͢ΔͱεϥΠυͷେ͖͕͞Γͳ͍ͷͰ pug Λ͍·͢ <ul class="list-group"> <li class="list-group-item">foo</li> <li class="list-group-item">bar</li> </ul>
pagesσΟϨΫτϦʹ.vueϑΝΠϧΛஔ pages !"" index.vue #"" tasks #"" index.vue λεΫҰཡIUUQMPDBMIPTUUBTLT pages
ʹϑΝΠϧΛஔ͢Ε vue-router ͷ ઃఆΛࣗಈతʹͬͯ͘Ε·͢ τοϓϖʔδIUUQMPDBMIPTU
./pages/index.vue <template lang="pug"> section.container nuxt-link(to="/tasks") λεΫҰཡ </template> τοϓϖʔδ IUUQMPDBMIPTU •
nuxt-link ίϯϙʔωϯτͰผ vue ͷભҠ • ੜ͞ΕΔͷaλάͰ͕͢ɺઌಡΈͯ͠ύϑΥʔϚϯεΛߴΊͯ͘ΕΔ
./pages/tasks/index.vue (λεΫҰཡશମ૾) <template lang="pug"> section.container.pt-5 .row .col-6 .card .card-header Δ͜ͱ
ul.list-group.list-group-flush.px-3 li.list-group-item(v-for="task in unfinishedTasks" :key="task.id") input.form-check-input( :id="`task-checkbox-${task.id}`" v-model="task.finished" type="checkbox") label(:for="`task-checkbox-${task.id}`") {{ task.title }} .col-6 .card .card-header ͬͨ͜ͱ ul.list-group.list-group-flush.px-3 li.list-group-item(v-for="task in finishedTasks" :key="task.id") input.form-check-input( :id="`task-checkbox-${task.id}`" v-model="task.finished" type="checkbox") label(:for="`task-checkbox-${task.id}`") {{ task.title }} </template> <script> export default { data() { return { tasks: [ { id: 1, title: 'ڇೕΛങ͏', finished: false }, { id: 2, title: 'ͨ·͝Λങ͏', finished: false }, ] } }, computed: { finishedTasks() { return this.tasks.filter((task) => { return task.finished }) }, unfinishedTasks() { return this.tasks.filter((task) => { return !task.finished }) } }, } </script> IUUQMPDBMIPTUUBTLT UFNQMBUF TDSJQU ࣍ͷϖʔδͰॱʹઆ໌͠·͢ ΛڽΒͯ͠ಡ·ͳͯ͘େৎ
<script> <script> export default { data() { return { tasks:
[ { id: 1, title: 'ڇೕΛങ͏', finished: false }, { id: 2, title: 'ͨ·͝Λങ͏', finished: false }, ] } }, computed: { finishedTasks() { return this.tasks.filter((task) => { return task.finished }) }, unfinishedTasks() { return this.tasks.filter((task) => { return !task.finished }) } }, } </script> EBUB DPNQVUFE ͬͨ͜ͱҰཡ pOJTIFE pOJTIFEϑϥάΛΓସ͑Δ Δ͜ͱҰཡ pOJTIFE
<template> <template lang="pug"> section.container .card .card-header Δ͜ͱ ul li(v-for="task in
unfinishedTasks" :key="task.id") input( :id="`task-checkbox-${task.id}`" v-model="task.finished" type="checkbox") label(:for="`task-checkbox-${task.id}`") {{ task.title }} .card .card-header ͬͨ͜ͱ ul li(v-for="task in finishedTasks" :key="task.id") input( :id="`task-checkbox-${task.id}`" v-model="task.finished" type="checkbox") label(:for="`task-checkbox-${task.id}`") {{ task.title }} </template> νΣοΫϘοΫε WNPEFMͰσʔλͱଓ λΠτϧ UBTLUJUMFΛࢀর
։ൃͷྲྀΕৼΓฦΓ • ϓϩδΣΫτ࡞ • λεΫҰཡը໘࡞ /pages • λεΫҰཡ෦ΛίϯϙʔωϯτԽ /components w
શମϨΠΞτ w EBUBߟ͑Δ w EBUBͷมߋํ๏ߟ͑Δ w ཧ
/pages ͷΈʹ͍ͭͯ͏ͪΐͬͱ pages └── tasks ├── _id.vue └── _userId └──
edit.vue w IUUQMPDBMIPTUUBTLT w QBHFTUBTLT@JEWVF w UIJTSPVUFQBSBNTJEͰಘΒΕΔ w IUUQMPDBMIPTUUBTLTFEJU w QBHFTUBTLT@VTFS*EFEJUWVF w ϋϚΓϙΠϯτ w ಉ֊ʹಉ໊͡લ @JE Λ͏ͱOVYUDIJMEͷѻ͍ʹͳΔ • _ ࢝·ΓಈతϧʔςΟϯά • _id ͷ෦ԿͰྑ͍
·ͱΊ • TODOফ͠ࠐΈػೳΛNuxt.jsͰ࡞ͬͯΈͨ • pages ʹ vue ϑΝΠϧΛஔ͢Δϧʔϧ (ઃఆΑΓن) •
ࠓճհͨ͠ͷ΄ΜͷҰ෦ (layouts, store, middleware, …) • ͘͢͝؆୯ʹ࢝ΊΒΕΔͷͰɺࠓिʹͰ npx create- nuxt-app <project-name> ʂ
λεΫҰཡΛίϯϙʔωϯτԽ͢Δ
<template lang="pug"> section.container .card .card-header Δ͜ͱ task-list(:tasks="unfinishedTasks" @check="onTaskCheck") .card .card-header
ͬͨ͜ͱ task-list(:tasks="finishedTasks" @check="onTaskCheck") </template> <script> import TaskList from '~/components/TaskList.vue' export default { components: { TaskList }, data() { return { tasks: [ { id: 1, title: 'ڇೕΛങ͏', finished: false }, { id: 2, title: 'ͨ·͝Λങ͏', finished: false }, ] } }, computed: { finishedTasks() { return this.tasks.filter((task) => { return task.finished }) }, unfinishedTasks() { return this.tasks.filter((task) => { return !task.finished }) } }, methods: { onTaskCheck(taskId) { const task = this.tasks.find(task => task.id === taskId) this.$set(task, 'finished', !task.finished) } } } </script> ./pages/tasks/index.vue <template lang="pug"> ul.list-group.list-group-flush.px-3 li.list-group-item( v-for="task in tasks" :key="task.id") input.form-check-input( :id="`task-checkbox-${task.id}`" :checked="task.finished" @change="$emit('check', task.id)" type="checkbox") label(:for="`task-checkbox-${task.id}`") |{{ task.title }} </template> <script> export default { props: { tasks: { type: Array, required: true } } } </script> ./components/TaskList.vue DIFDLΠϕϯτൃՐ UBTLpOJTIFEస