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
Rails使いのNuxt.js入門 - 銀座Rails#12
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
180
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
140
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
14
5.9k
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
200
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
290
さぁV100、メモリをお食べ・・・
nilpe
0
160
Contextとはなにか
chiroruxx
1
380
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
810
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.5k
Datadog LLM Observabilityで実現する 安全なLLM Usage 管理
3150
0
120
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
750
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
9.9k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
310
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
240
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
250
Practical Orchestrator
shlominoach
191
11k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
200
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Believing is Seeing
oripsolob
1
150
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స